Example #1
0
    async def render_post(self, request):
        status = DMStatus.ST_UNSPEC
        good_addrs = []
        bad_addrs = []

        # Incoming TLVs parsing
        in_pload = ThreadTLV.sub_tlvs_str(request.payload)
        logging.info('in %s req: %s' % (URI.N_MR, in_pload))

        # BBR Primary/Secondary status
        if not 'primary' in db.get('bbr_status'):
            status = DMStatus.ST_NOT_PRI
        else:
            timeout = None
            comm_sid = None

            # IPv6 Addresses TLV
            addrs_value = ThreadTLV.get_value(request.payload,
                                              TLV.A_IPV6_ADDRESSES)
            if addrs_value:
                status, good_addrs, bad_addrs = Res_N_MR._parse_addrs(
                    addrs_value)

            # Timeout TLV
            timeout = ThreadTLV.get_value(request.payload, TLV.A_TIMEOUT)

            # Commissioner Session ID TLV
            comm_sid = ThreadTLV.get_value(request.payload,
                                           TLV.A_COMMISSIONER_SESSION_ID)

            # Register valid addresses
            if good_addrs:
                if timeout and comm_sid:
                    addr_tout = timeout
                else:
                    addr_tout = db.get('mlr_timeout') or DEFS.MIN_MLR_TIMEOUT
                reg_addrs = []
                reg_addrs_bytes = []
                for addr_bytes in good_addrs:
                    reg_addrs.append(
                        ipaddress.IPv6Address(addr_bytes).compressed)
                    reg_addrs_bytes += addr_bytes
                MCAST_HNDLR.reg_update(reg_addrs, addr_tout)
                # Send BMLR.ntf
                ipv6_addressses_tlv = ThreadTLV(
                    t=TLV.A_IPV6_ADDRESSES,
                    l=16 * len(good_addrs),
                    v=reg_addrs_bytes)
                timeout_tlv = ThreadTLV(
                    t=TLV.A_TIMEOUT, l=4, v=struct.pack('!I', addr_tout))
                payload = ipv6_addressses_tlv.array() + timeout_tlv.array()
                dst = '%s%%%s' % (db.get('all_network_bbrs'),
                                  db.get('exterior_ifname'))
                client = CoapClient()
                await client.non_request(dst, DEFS.PORT_BB, URI.B_BMR, payload)
                client.stop()

        # Fill and return the response
        out_pload = ThreadTLV(t=TLV.A_STATUS, l=1, v=[status]).array()
        addrs_payload = []
        for elem in bad_addrs:
            addrs_payload += elem
        if bad_addrs:
            out_pload += ThreadTLV(
                t=TLV.A_IPV6_ADDRESSES,
                l=16 * len(bad_addrs),
                v=bytes(addrs_payload)).array()
        logging.info(
            'out %s rsp: %s' % (URI.N_MR, ThreadTLV.sub_tlvs_str(out_pload)))
        return aiocoap.Message(code=Code.CHANGED, payload=out_pload)
Example #2
0
    async def render_post(self, request):
        status = DMStatus.ST_UNSPEC
        good_addrs = []
        bad_addrs = []

        # Incoming TLVs parsing
        in_pload = ThreadTLV.sub_tlvs_str(request.payload)
        logging.info('in %s req: %s' % (URI.N_MR, in_pload))

        # Thread Harness may force response status
        mlr_next_status = db.get('mlr_next_status')
        if kibra.__harness__ and mlr_next_status:
            status = int(mlr_next_status)
            db.set('mlr_next_status', '')
            # Include bad addresses for resources shortage status
            if status == DMStatus.ST_NOT_PRI:
                # IPv6 Addresses TLV
                addrs_value = ThreadTLV.get_value(request.payload,
                                                  TLV.A_IPV6_ADDRESSES)
                if addrs_value:
                    _, good, bad = Res_N_MR.parse_addrs(addrs_value)
                    bad_addrs.append(good)
                    bad_addrs.append(bad)
        # BBR Primary/Secondary status
        elif not 'primary' in db.get('bbr_status'):
            status = DMStatus.ST_NOT_PRI
        # Resources shortage
        elif len(MCAST_HNDLR.maddrs) >= MULTICAST_LIMIT:
            status = DMStatus.ST_RES_SHRT
        # Normal registration
        else:
            timeout = None
            comm_sid = None

            # IPv6 Addresses TLV
            addrs_value = ThreadTLV.get_value(request.payload,
                                              TLV.A_IPV6_ADDRESSES)
            if addrs_value:
                status, good_addrs, bad_addrs = Res_N_MR.parse_addrs(
                    addrs_value)

            # Timeout TLV
            timeout = ThreadTLV.get_value(request.payload, TLV.A_TIMEOUT)

            # Commissioner Session ID TLV
            comm_sid = ThreadTLV.get_value(request.payload,
                                           TLV.A_COMMISSIONER_SESSION_ID)

            # Register valid addresses
            if good_addrs:
                if timeout and comm_sid:
                    addr_tout = struct.unpack('!I', timeout)[0]
                else:
                    addr_tout = db.get('mlr_timeout') or DEFS.MIN_MLR_TIMEOUT
                reg_addrs = []
                reg_addrs_bytes = []
                for addr_bytes in good_addrs:
                    reg_addrs.append(
                        ipaddress.IPv6Address(addr_bytes).compressed)
                    reg_addrs_bytes += addr_bytes
                MCAST_HNDLR.reg_update(reg_addrs, addr_tout)

                # Send BMLR.ntf
                ipv6_addressses_tlv = ThreadTLV(t=TLV.A_IPV6_ADDRESSES,
                                                l=16 * len(good_addrs),
                                                v=reg_addrs_bytes)
                timeout_tlv = ThreadTLV(t=TLV.A_TIMEOUT,
                                        l=4,
                                        v=struct.pack('!I', addr_tout))
                net_name = db.get('ncp_netname').encode()
                network_name_tlv = ThreadTLV(t=TLV.A_NETWORK_NAME,
                                             l=len(net_name),
                                             v=net_name)
                payload = (ipv6_addressses_tlv.array() + timeout_tlv.array() +
                           network_name_tlv.array())
                dst = '%s%%%s' % (db.get('all_network_bbrs'),
                                  db.get('exterior_ifname'))
                await MCAST_HNDLR.coap_client.non_request(
                    dst, DEFS.PORT_BB, URI.B_BMR, payload)

        # Fill and return the response
        out_pload = ThreadTLV(t=TLV.A_STATUS, l=1, v=[status]).array()
        addrs_payload = []
        for elem in bad_addrs:
            addrs_payload += elem
        if bad_addrs:
            out_pload += ThreadTLV(t=TLV.A_IPV6_ADDRESSES,
                                   l=16 * len(bad_addrs),
                                   v=bytes(addrs_payload)).array()
        logging.info('out %s rsp: %s' %
                     (URI.N_MR, ThreadTLV.sub_tlvs_str(out_pload)))
        return aiocoap.Message(code=Code.CHANGED, payload=out_pload)