示例#1
0
    def update_lenddev(self, dev_eui, **kwargs):
        """Add new End Device."""
        dev_eui = EUI64(dev_eui)
        desc = kwargs.get("desc", "Generic End Device")
        join_eui = EUI64(kwargs.get("joinEUI", ""))
        app_key = kwargs.get("appKey")
        nwk_key = kwargs.get("nwkKey")

        try:
            lenddev = self.lenddevs[dev_eui]
        except KeyError:
            raise KeyError("End Device %s not registered in \
                           the LNS Server" % dev_eui)
        if join_eui:
            lenddev.join_eui = join_eui
        if app_key:
            lenddev.app_key = app_key
        if nwk_key:
            lenddev.nwk_key = nwk_key
        if desc:
            lenddev.desc = desc

        lenddev.save()
        self.lenddevs[dev_eui] = lenddev
        return self.lenddevs[dev_eui]
示例#2
0
    def delete(self, *args, **kwargs):
        """Delete one or all LoRaWAN GTW from LSN Discovery Server.

        Args:

            [0]: the lnss euid
            [1]: the lgtw euid

        Example URLs:

            DELETE /api/v1/lnsd/lnss/0000:0000:0000:0001/lgtws
            DELETE /api/v1/lnsd/lnss/0000:0000:0000:0001/lgtws/
                b827:ebff:fee7:7681
        """
        lns_euid = None
        lgtw_euid = None

        if args[0]:
            lns_euid = EUI64(args[0])

        if len(args) == 2:
            if args[1]:
                lgtw_euid = EUI64(args[1])

        if len(args) == 2 and lns_euid and lgtw_euid:
            self.service.remove_lgtw(lgtw_euid, lns_euid)
        elif len(args) == 2 and not lns_euid and lgtw_euid:
            self.service.remove_lgtw(lgtw_euid)
        elif lns_euid:
            for lgtw_euid in self.service.lgtws:
                self.service.remove_lgtw(lgtw_euid, lns_euid)
        else:
            for lns_euid in self.service.lnss:
                for lgtw_euid in self.service.lgtws:
                    self.service.remove_lgtw(lgtw_euid, lns_euid)
    def _handle_jreq(self, join_msg, rxtime):
        """Handle an incoming Join Request from a device.

        Args:
            join_msg, a JOIN message
        Returns:
            None
        """
        data = {}
        data["radio_data"] = self._handle_radio_data(join_msg, rxtime)
        data["rxtime"] = rxtime
        data["join_data"] = {}
        try:
            data["join_data"]["MHdr"] = join_msg["MHdr"]
            data["join_data"]["JoinEui"] = EUI64(join_msg["JoinEui"])
            data["join_data"]["DevEui"] = EUI64(join_msg["DevEui"])
            data["join_data"]["DevNonce"] = join_msg["DevNonce"]
            data["join_data"]["MIC"] = join_msg["MIC"] & (2**32 - 1)
            data["xtime"] = join_msg['upinfo']["xtime"]
            # internal time of the lGTW
            data["rctx"] = join_msg['upinfo']["rctx"]
            # specifies the antenna used
        except KeyError as err:
            LOG.info("Malformed Join Request")
            LOG.info(err)
        else:
            data["PhyPayload"] = struct.pack("<BQQHI", join_msg["MHdr"],
                                             int(data["join_data"]["JoinEui"]),
                                             int(data["join_data"]["DevEui"]),
                                             # TODO check if int(value,16)
                                             # is needed
                                             #  int(data["join_data"]["JoinEui"],
                                             #      16),
                                             #  int(data["join_data"]["DevEui"],
                                             #      16),
                                             join_msg["DevNonce"] & 0xFFFF,
                                             join_msg["MIC"] &
                                             (2**32 - 1)).hex()
            if data["join_data"]["DevEui"] in self.server.lenddevs:
                LOG.info(data["join_data"])
                # TODO implementation of Join Data handling
            else:
                LOG.info("Device %s  is not in the database",
                         data["join_data"]["DevEui"])

            # Call registered callbacks
            data["msg"] = join_msg
            self.call_registered_callbacks(lnsp.PT_JOIN_REQ, **data)
示例#4
0
    def update_lgtw(self, lgtw_euid, **kwargs):
        """Update lGTW in the LNS database."""
        lgtw_euid = EUI64(lgtw_euid)
        desc = kwargs.get("desc")
        name = kwargs.get("name")
        owner = str(kwargs.get("owner"))
        lgtw_config = kwargs.get("lgtw_config")

        if lgtw_euid not in self.lgtws:
            raise ValueError("GTW %s not registered in the \
                             LNS Server" % lgtw_euid)

        try:
            lgtw = self.lgtws[lgtw_euid]
        except KeyError:
            raise KeyError("%s not registered, \
                           register lgtw first" % lgtw_euid)

        if owner:
            lgtw.owner = owner
        if name:
            lgtw.name = name
        if desc:
            lgtw.desc = desc
        if lgtw_config:
            lgtw.lgtw_config = lgtw_config

        self.lgtws[lgtw_euid] = lgtw.save()

        return self.lgtws[lgtw_euid]
示例#5
0
    def post(self, *args, **kwargs):
        """Add a new LNS to the LNS Discovery Server Database.

        Request:

            version: protocol version (1.0)
            euid: the lns id in eui64 or euid format (mandatory)
            uri: the lns uri template (mandatory)
            desc: a human readable description of the device (optional)
            lgtws: the of lGTWS (optional)

        Example URLs:

            POST /api/v1/lnsd/lnss/"::1"

            {
                "version":"1.0",
                "euid": "0000:0000:0000:0001",
                "lgtws":["b827:ebff:fee7:7681"],
                "uri":"ws://0.0.0.0:6038/router-",
                "desc": "Generic LNS"
            }
        """

        kwargs['euid'] = EUI64(kwargs['euid'])

        lnss = self.service.add_lns(**kwargs)

        self.set_header("Location", "/api/v1/lnsd/lnss/%s" % lnss.euid)
示例#6
0
    def put(self, *args, **kwargs):
        """Add a new LNS to the LNS Discovery Server Database.

        Args:

            [0]: the lns id in eui64 or euid format (mandatory)

        Request:

            version: protocol version (1.0)
            uri: the lns uri template (mandatory)
            desc: a human readable description of the device (optional)
            lgtws: the of lGTWS (optional)

        Example URLs:

            PUT /api/v1/lnsd/lnss/::1

            {
                "version":"1.0",
                "lgtws":["b827:ebff:fee7:7681"],
                "uri":"ws://0.0.0.0:6038/router-",
                "desc": "Generic LNS"
            }
        """

        self.service.update_lns(euid=EUI64(args[0]), **kwargs)
    def open(self, *args: str, **kwargs: str):
        """Exec code when a new WebSocket is opened.

        The arguments to `open` are extracted from
        the `tornado.web.URLSpec` regular expression,
        just like the arguments to `tornado.web.RequestHandler.get`.
        """
        lgtw_euid = EUI64(args[0])
        try:
            self.lgtw = self.server.lgtws[lgtw_euid]
        except KeyError:
            LOG.info("Unregistered lGtw (%s), closing connection",
                     lgtw_euid)
            self.close()
            return

        # save lGTW IP address
        self.lgtw.ipaddr = self.request.remote_ip
        self.lgtw.last_seen_ts = datetime.now().timestamp()
        self.lgtw.save()  # REVIEW test
        # save lGTW connection
        self.lgtw.connection = self
        # set lGTW state to CONNECTED
        self.lgtw.set_connected()
        LOG.info("Connected to lGtw %s", self.lgtw.lgtw_euid.id6)
    def get(self, *args, **kwargs):
        """List LoRaWAN End devices.

        Args:
            [0]: devEUI (optional)

        Example URLs:
            GET /api/v1/lns/lenddevs
            [
                {
                    "devEUI": "0028A154B89172D2"
                    "devAddr": "0028A154B89172D2",
                    "desc": "End Device XXX"
                }
            ]

            GET /api/v1/lns/lenddevs/00:28:A1:54:B8:91:72:D2
            {
                    "devAddr": "0028A154B89172D2",
                    "desc": "End Device XXX"
            }
        """
        if not args:
            out = []
            for key in self.service.lenddevs:
                out.append(self.service.lenddevs[key].to_dict())
            return out

        dev_eui = EUI64(args[0])
        print(self.service.lenddevs)
        return self.service.lenddevs[dev_eui].to_dict()
示例#9
0
 def remove_lgtw(self, lgtw_euid):
     """Remove GTW from LNS database."""
     lgtw_euid = EUI64(lgtw_euid)
     if lgtw_euid not in self.lgtws:
         raise KeyError("GTW %s not registered" % lgtw_euid)
     lgtw = self.lgtws[lgtw_euid]
     lgtw.delete()
     del self.lgtws[lgtw_euid]
示例#10
0
 def remove_lenddev(self, dev_eui):
     """Remove End Device."""
     dev_eui = EUI64(dev_eui)
     if dev_eui not in self.lenddevs:
         raise KeyError("End Device %s not registered" % dev_eui)
     lenddev = self.lenddevs[dev_eui]
     lenddev.delete()
     del self.lenddevs[dev_eui]
示例#11
0
    def get(self, *args, **kwargs):
        """List LoRaWAN Gateways.

        Args:
            [0]: the LoRaWAN Gateway EUID (optional)

        Example URLs:
            GET /api/v1/lns/lgtws
            [
                {"lgtw_euid": "b8:27:eb:ff:fe:e7:76:81",
                "desc": "iC880A Concentrator",
                "state": "disconnected",
                "owner": "00:00:00:00:00:00:00:00",
                "lgtw_version": [...],
                "lgtw_config": [...],
                "last_seen": "2020-02-18 12:40:52",
                "last_seen_ts": 1582026052.0,
                "connection": null},
                {[...]},
            ]

            GET /api/v1/lns/lgtws/b8:27:eb:ff:fe:e7:76:81
                {
                "lgtw_euid": "b8:27:eb:ff:fe:e7:76:81",
                "desc": "iC880A Concentrator",
                "state": "disconnected",
                "owner": "00:00:00:00:00:00:00:00",
                "lgtw_version": [...],
                "lgtw_config": [...],
                "last_seen": "2020-02-18 12:40:52",
                "last_seen_ts": 1582026052.0,
                "connection": null
                }
        """
        out = []
        desc = self.get_argument("desc", None)
        name = self.get_argument("name", None)

        if len(args) == 1:
            lgtw_euid = EUI64(args[0])

            if lgtw_euid in self.service.lgtws:
                lgtw = self.service.lgtws[lgtw_euid].to_dict()
                if not ((desc and (desc not in lgtw["desc"])) or
                        (name and (name not in lgtw["name"]))):
                    out = [lgtw]
            return out

        for key in self.service.lgtws:
            if (desc
                    and desc not in self.service.lgtws[key].to_dict()["desc"]):
                continue
            if (name
                    and name not in self.service.lgtws[key].to_dict()["name"]):
                continue
            out.append(self.service.lgtws[key].to_dict())
        return out
示例#12
0
 def add_lenddev(self, dev_eui, **kwargs):
     """Add new End Device."""
     dev_eui = EUI64(dev_eui)
     if dev_eui in self.lenddevs:
         raise ValueError(
             "End Device %s already registered in the LNS Server" % dev_eui)
     kwargs["dev_eui"] = dev_eui
     lenddev = LoRaWANEndDev(**kwargs).save()
     self.lenddevs[dev_eui] = lenddev
     return self.lenddevs[dev_eui]
示例#13
0
    def add_lns(self, euid, uri, lgtws, desc="Generic LNS"):
        """Add a new LNS. Overwrites LNS if it already exists."""

        if euid in self.lnss:
            raise ValueError("LNS %s already defined" % euid)

        lgtws = [EUI64(lgtw).id6 for lgtw in lgtws]
        lns = LNS(uri=uri, euid=euid, desc=desc, lgtws=lgtws).save()
        self.lnss[euid] = lns

        return self.lnss[euid]
示例#14
0
    def post(self, *args, **kwargs):
        """Add a new LoRaWAN GTW to the LNS Discovery Server Database.

        Args:

            [0]: the lnss euid (mandatory)
            [1]: the lgtw euid (mandatory)

        Example URLs:

            POST /api/v1/lnsd/lnss/0000:0000:0000:0001/lgtws/
                b827:ebff:fee7:7681
        """

        lns_euid = EUI64(args[0])
        lgtw_euid = EUI64(args[1])

        self.service.add_lgtw(lns_euid=lns_euid, lgtw_euid=lgtw_euid)

        self.set_header(
            "Location",
            "/api/v1/lnsd/lnss/%s/lgtws/%s" % (lns_euid, lgtw_euid))
示例#15
0
    def update_lns(self, euid, uri, lgtws, desc="Generic LNS"):
        """Update LNS data."""

        lns = self.lnss[euid]

        try:
            lns.uri = uri
            lns.desc = desc
            lns.lgtws = [EUI64(lgtw) for lgtw in lgtws]
            lns.save()
        finally:
            lns.refresh_from_db()

        return self.lnss[euid]
示例#16
0
    def delete(self, *args, **kwargs):
        """Delete one or all LoRaWAN end devices.

        Args:
            [0]: the lGTW euid

        Example URLs:
            DELETE /api/v1/lns/lgtws
            DELETE /api/v1/lns/lgtws/08:27:eb:ff:fe:e7:76:91
        """
        if args:
            self.service.remove_lgtw(EUI64(args[0]))
        else:
            self.service.remove_all_lgtws()
    def delete(self, *args, **kwargs):
        """Delete one or all LoRaWAN end devices.

        Args:
            [0]: devEUI

        Example URLs:
            DELETE /api/v1/lns/lenddevs
            DELETE /api/v1/lns/lenddevs/00:28:A1:54:B8:91:72:D2
        """
        if args:
            self.service.remove_lenddev(EUI64(args[0]))
        else:
            self.service.remove_all_lenddevs()
示例#18
0
    def handle_message(self, msg):
        """Handle incoming message."""
        try:
            self.lgtw_id = EUI64(msg['router'])
        except KeyError:
            LOG.error("Bad message formatting, 'router' information"
                      "(Radio GTW EUI) missing")
            return

        LOG.info("New LNS discovery request from %s: %s", self.lgtw_id,
                 json.dumps(msg))

        self.send_lns_discovery_request_replay()

        return
示例#19
0
    def add_lns(self, euid, uri, lgtws=None, desc="Generic LNS"):
        """Add a new LNS."""

        if euid in self.lnss:
            raise ValueError("LNS %s already defined" % euid)

        if not lgtws:
            lgtws = []
        else:
            lgtws = [EUI64(lgtw).id6 for lgtw in lgtws]

        lns = LNS(uri=uri, euid=euid, desc=desc, lgtws=lgtws).save()

        self.lnss[euid] = lns

        return self.lnss[euid]
示例#20
0
    def delete(self, *args, **kwargs):
        """Delete one or all devices.

        Args:
            [0]: the lns id in eui64 or euid format (optional)

        Example URLs:

            DELETE /api/v1/lnsd/lnss
            DELETE /api/v1/lnsd/lnss/::1
        """

        if args:
            self.service.remove_lns(EUI64(args[0]))
        else:
            self.service.remove_all_lnss()
示例#21
0
    def update_lns(self, euid, uri, lgtws=None, desc="Generic LNS"):
        """Update LNS data."""

        lns = self.lnss[euid]

        if not lgtws:
            lgtws = []
        else:
            lgtws = [EUI64(lgtw).id6 for lgtw in lgtws]

        try:
            lns.uri = uri
            lns.desc = desc
            lns.lgtws = lgtws
            lns.save()
        finally:
            lns.refresh_from_db()

        return self.lnss[euid]
示例#22
0
    def add_lgtw(self, lgtw_euid, **kwargs):
        """Add lGTW to LNS database."""
        lgtw_euid = EUI64(lgtw_euid)
        name = kwargs.get("name", "BasicStation")
        desc = kwargs.get("desc", "Generic GTW")
        owner = str(kwargs.get("owner", lnsp.DEFAULT_OWNER))
        lgtw_config = kwargs.get("lgtw_config", self.lgtw_settings)

        if lgtw_euid in self.lgtws:
            raise ValueError("GTW %s already registered in the LNS Server" %
                             lgtw_euid)

        self.lgtws[lgtw_euid] = LoRaWANgtw(lgtw_euid=lgtw_euid,
                                           desc=desc,
                                           owner=owner,
                                           name=name,
                                           lgtw_config=lgtw_config).save()

        return self.lgtws[lgtw_euid]
示例#23
0
    def get(self, *args, **kwargs):
        """List devices.

        Args:
            [0]: the lns euid (optional)

        Example URLs:

            GET /api/v1/lnsd/lnss

            [
                {
                    "euid": "0000:0000:0000:0001",
                    "desc": "Generic LNS",
                    "uri": "ws://0.0.0.0:6038/router-",
                    "lgtws": [
                        "b827:ebff:fee7:7681"
                    ],
                    "last_seen": 0,
                    "last_seen_ts": "1970-01-01T01:00:00.000000Z",
                    "period": 0
                }
            ]

            GET /api/v1/lnsd/lnss/::1

            {
                "euid": "0000:0000:0000:0001",
                "desc": "Generic LNS",
                "uri": "ws://0.0.0.0:6038/router-",
                "lgtws": [
                    "b827:ebff:fee7:7681"
                ],
                "last_seen": 0,
                "last_seen_ts": "1970-01-01T01:00:00.000000Z",
                "period": 0
            }

        """

        return self.service.lnss \
            if not args else self.service.lnss[EUI64(args[0])]
示例#24
0
 def handle_add_lgtw(self, euid):
     """Save whe the lEndDev is seen by a new lGTW."""
     if str(EUI64(euid)) not in self.lgtws_range:
         self.lgtws_range.append(euid)
示例#25
0
    def get(self, *args, **kwargs):
        """List devices.

        Args:
            [0]: the lnss euid (optional)
            [1]: the lgtw euid (optional)

        Example URLs:
            GET /api/v1/lnsd/lnss/0000:0000:0000:0001/lgtws

            {
                "lns_euid": "0000000000000001",
                "lgtw_euid": [
                    "b827ebfffee77681"
                ]
            }

            GET /api/v1/lnsd/lnss/0000:0000:0000:0001/lgtws/b827:ebff:fee7:7681

            {
                "lns_euid": "0000000000000001",
                "lgtw_euid": "b827ebfffee77681"
            }
        """

        lns_euid = args[0]
        lgtw_euid = args[1] if len(args) == 2 else None

        out = []

        if lns_euid:
            lns_euid = EUI64(lns_euid)

        if lgtw_euid:
            lgtw_euid = EUI64(args[1])

        if not lns_euid and not lgtw_euid:
            # E.g. GET /api/v1/lnsd/lnss//lgtws/
            for key in self.service.lnss:
                out.append({
                    "lns_euidx": EUI64(key),
                    "lgtw_euids": self.service.lnss[key].lgtws
                })

        elif (lns_euid in self.service.lnss
              and lgtw_euid in self.service.lnss[lns_euid].lgtws):
            # E.g. GET
            # /api/v1/lnsd/lnss/0000:0000:0000:0001/lgtws/b827:ebff:fee7:7681
            out = {"lns_euid": lns_euid, "lgtw_euid": lgtw_euid}

        elif lns_euid in self.service.lnss and not lgtw_euid:
            # E.g.
            # GET /api/v1/lnsd/lnss/0000:0000:0000:0001/lgtws/
            out = {
                "lns_euid": lns_euid,
                "lgtw_euid": self.service.lnss[lns_euid].lgtws
            }

        elif not lns_euid and lgtw_euid in self.service.lgtws:
            # E.g.
            # GET /api/v1/lnsd/lnss//lgtws/b827:ebff:fee7:7681
            for key in self.service.lgtws[lgtw_euid]:
                out.append({"lns_euid": EUI64(key), "lgtw_euid": [lgtw_euid]})

        else:

            raise KeyError("Unable to find pair (%s, %s)" %
                           (lns_euid, lgtw_euid))

        return out