コード例 #1
0
    def test_steer_to_band(self):
        """Verify the parsing of the steer to band message."""
        # Test 1: Valid steer to band messages (Version 1)
        test_cases = itertools.product(
            [BAND_TYPE.BAND_24G, BAND_TYPE.BAND_5G, BAND_TYPE.BAND_INVALID],
            [BAND_TYPE.BAND_24G, BAND_TYPE.BAND_5G])
        for test_case in test_cases:
            # Steer to band with the given associated band (the first
            # element of test_case) and target band (the second element
            # of test_case).
            mac = '\x94\x45\x8d\x13\xb7\x86'
            msg = '\x00' + mac + chr(test_case[0].value) + chr(
                test_case[1].value)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION1, False, msg)
            self.assertEquals(
                steerexec.SteerToBand._make(
                    (common.ether_ntoa(mac), test_case[0], test_case[1])),
                payload)

            # Same as above but in big-endian (which makes no difference)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION1, True, msg)
            self.assertEquals(
                steerexec.SteerToBand._make(
                    (common.ether_ntoa(mac), test_case[0], test_case[1])),
                payload)

        # Test 2: Invalid target band (Version 1)
        mac = '\x49\xcd\x30\xda\x0c\x4c'
        msg = '\x00' + mac + '\x01\x02'
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION1, False, msg)
コード例 #2
0
    def test_dual_band_update(self):
        """Verify the parsing of the dual band update message."""
        # Test 1: Device becomes dual band
        mac = '\x91\x89\x0e\x16\xfb\x4e'
        msg = '\x03' + mac + '\x01'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, False, msg)
        self.assertEquals(stadb.DualBandUpdate._make(
            (common.ether_ntoa(mac), True)),
            payload)

        # Same as above but in big-endian (which makes no difference)
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, True, msg)
        self.assertEquals(stadb.DualBandUpdate._make(
            (common.ether_ntoa(mac), True)),
            payload)

        # Test 2: Device is no longer considered dual band
        mac = '\x3b\x16\xf7\x1c\xbc\xd7'
        msg = '\x03' + mac + '\x00'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, False, msg)
        self.assertEquals(stadb.DualBandUpdate._make(
            (common.ether_ntoa(mac), False)),
            payload)

        # Same as above but in big-endian (which makes no difference)
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, True, msg)
        self.assertEquals(stadb.DualBandUpdate._make(
            (common.ether_ntoa(mac), False)),
            payload)
コード例 #3
0
    def test_beacon_report(self):
        mac = '\x42\x62\x89\x67\x4d\xb4'
        # Test 1: Measurement on APID = 0xFF, channel = 100, essId = 0,
        #         RCPI = -10
        msg = '\x03' + mac + '\xFF\x64\x00\xF6'
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION2,
                                                   False, msg)
        self.assertEquals(
            wlanif.BeaconReport._make(
                (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0), -10)),
            payload)

        # Test 2: Similar but in big endian format (which makes no difference)
        msg = '\x03' + mac + '\xFF\x64\x00\xF6'
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION2,
                                                   True, msg)
        self.assertEquals(
            wlanif.BeaconReport._make(
                (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0), -10)),
            payload)

        # Test 3: Not supported in version 1
        msg = '\x03' + mac + '\xFF\x64\x00\xF6'
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION1, False, msg)
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION1, True, msg)
コード例 #4
0
    def test_abort_steer_to_band(self):
        """Verify the parsing of the abort steer to band message."""
        # Test 1: Valid steer to band messages
        for disabled_band in [BAND_TYPE.BAND_24G, BAND_TYPE.BAND_5G]:
            # Abort steer to band with the given disabled band.
            mac = '\x94\x45\x8d\x13\xb7\x86'
            msg = '\x01' + mac + chr(disabled_band.value)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION1, False, msg)
            self.assertEquals(
                steerexec.AbortSteerToBand._make(
                    (common.ether_ntoa(mac), disabled_band)), payload)

            # Same as above but in big-endian (which makes no difference)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION1, True, msg)
            self.assertEquals(
                steerexec.AbortSteerToBand._make(
                    (common.ether_ntoa(mac), disabled_band)), payload)

        # Test 2: Invalid disabled band
        mac = '\x49\xcd\x30\xda\x0c\x4c'
        msg = '\x01' + mac + '\x02'
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION1, False, msg)
コード例 #5
0
    def test_interface(self):
        """Verify the parsing of the interface message v2."""
        mac = '\xec\x40\xe4\xe7\xf5\xa5'
        # SSID length + string (null terminated)
        ssid = '\x09' + '\x74\x65\x73\x74\x73\x73\x69\x64\x00'
        # iface name length + string
        iface = '\x04' + '\x61\x74\x68\x30'
        # Fixed length portion: mac, channel, essid
        msg = '\x02' + mac + '\x06\x01' + ssid + iface
        # Test 1: Valid message
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION2,
                                                   False, msg)
        self.assertEquals(
            wlanif.Interface._make(
                (common.ether_ntoa(mac), 6, 1, 9, "testssid\x00", 4, "ath0")),
            payload)

        # Test 2: Same, but in big endian
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION2,
                                                   True, msg)
        self.assertEquals(
            wlanif.Interface._make(
                (common.ether_ntoa(mac), 6, 1, 9, "testssid\x00", 4, "ath0")),
            payload)

        # Test 3: Invalid SSID length
        ssid = '\xff' + '\x74\x65\x73\x74\x73\x73\x69\x64'
        msg = '\x02' + mac + '\x06\x01' + ssid + iface
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION2, True, msg)

        # Test 4: Invalid interface length
        ssid = '\x08' + '\x74\x65\x73\x74\x73\x73\x69\x64'
        iface = '\xff' + '\x61\x74\x68\x30\x00'
        msg = '\x02' + mac + '\x06\x01' + ssid + iface
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION2, True, msg)

        # Test 5: Not supported in version 1
        iface = '\x05' + '\x61\x74\x68\x30\x00'
        msg = '\x02' + mac + '\x06\x01' + ssid + iface
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION1, False, msg)
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION1, True, msg)
コード例 #6
0
    def test_sta_pollution_changed_msg(self):
        """Verify the parsing of the STA pollution changed message."""
        # Test 1: Pollution changed on a BSS on channel 149
        test_cases = itertools.product([False, True], [
            STAPollutionChangeReason.POLLUTION_CHANGE_DETECTION,
            STAPollutionChangeReason.POLLUTION_CHANGE_AGING,
            STAPollutionChangeReason.POLLUTION_CHANGE_REMOTE,
            STAPollutionChangeReason.POLLUTION_CHANGE_INVALID
        ])
        for big_endian in (False, True):
            mac = '\x42\x62\x89\x67\x4d\xb4'
            for test_case in test_cases:
                msg = '\x03' + mac + '\xff\x95\x01' + \
                      chr(test_case[0]) + chr(test_case[1].value)
                payload = estimator.unpack_payload_from_bytes(
                    common.Version.VERSION2, big_endian, msg)
                self.assertEquals(
                    estimator.STAPollutionChanged._make(
                        (common.ether_ntoa(mac), common.BSSInfo(255, 149, 1),
                         test_case[0], test_case[1])), payload)

        # Test 2: Invalid pollution change reason
        for big_endian in (False, True):
            mac = '\x42\x62\x89\x67\x4d\xb4'
            for changed in (False, True):
                msg = '\x03' + mac + '\xff\x95\x01' + chr(changed) + \
                      chr(STAPollutionChangeReason.POLLUTION_CHANGE_INVALID.value + 1)
                self.assertRaises(MessageMalformedError,
                                  estimator.unpack_payload_from_bytes,
                                  common.Version.VERSION2, big_endian, msg)
コード例 #7
0
    def test_btm_compliance(self):
        """Verify the parsing of the BTM compliance message."""
        # Test 1: Valid BTM compliance messages
        for compliance in BTMComplianceType:
            for is_unfriendly in [False, True]:
                # Changing to all the valid compliance states.
                mac = '\x6e\xee\xb2\x94\x33\x6f'
                countFailure = '\x0a\x00\x00\x00'
                countFailureActive = '\x01\x00\x00\x00'
                msg = '\x04' + mac + chr(is_unfriendly) + chr(compliance.value) + \
                      countFailure + countFailureActive
                payload = steerexec.unpack_payload_from_bytes(
                    common.Version.VERSION2, False, msg)
                self.assertEquals(
                    steerexec.BTMCompliance._make(
                        (common.ether_ntoa(mac), is_unfriendly, compliance, 10,
                         1)), payload)

                # Same as above but in big-endian
                countFailure = '\x00\x00\x00\x0a'
                countFailureActive = '\x00\x00\x00\x01'
                msg = '\x04' + mac + chr(is_unfriendly) + chr(compliance.value) + \
                      countFailure + countFailureActive
                payload = steerexec.unpack_payload_from_bytes(
                    common.Version.VERSION2, True, msg)
                self.assertEquals(
                    steerexec.BTMCompliance._make(
                        (common.ether_ntoa(mac), is_unfriendly, compliance, 10,
                         1)), payload)

        # Test 2: Invalid BTM compliance type
        mac = '\x6e\xee\xb2\x94\x33\x6f'
        countFailure = '\x0a\x00\x00\x00'
        countFailureActive = '\x01\x00\x00\x00'
        msg = '\x04' + mac + '\x01' + '\x04' + countFailure + countFailureActive
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)

        # Test 3: Not supported in version 1
        mac = '\x6e\xee\xb2\x94\x33\x6f'
        msg = '\x04' + mac + '\x03' + '\x01' + countFailure + countFailureActive
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION1, False, msg)
コード例 #8
0
ファイル: test_common.py プロジェクト: lunatickochiya/ipq8074
    def test_ether_ntoa(self):
        """Test the function that formats an ethernet address as a string."""
        self.assertRaises(ValueError, common.ether_ntoa,
                          '\x11\x22\x33\x44\x55')  # too short
        self.assertRaises(ValueError, common.ether_ntoa,
                          '\x11\x22\x33\x44\x55\x66\x77')  # too long

        self.assertEquals('ff:c1:c4:62:22:53',
                          common.ether_ntoa('\xff\xc1\xc4\x62\x22\x53'))
コード例 #9
0
    def test_steering_prohibited(self):
        """Verify the parsing of the steering prohibited message."""
        # Test 1: Valid steering prohibited messages Version 2
        for prohibit_type in SteeringProhibitType:
            # Abort steer to band with the given disabled band.
            mac = '\x6e\xee\xb2\x94\x33\x6f'
            msg = '\x03' + mac + chr(prohibit_type.value)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION2, False, msg)
            self.assertEquals(
                steerexec.SteeringProhibited._make(
                    (common.ether_ntoa(mac), prohibit_type)), payload)

            # Same as above but in big-endian (which makes no difference)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION2, True, msg)
            self.assertEquals(
                steerexec.SteeringProhibited._make(
                    (common.ether_ntoa(mac), prohibit_type)), payload)

        # Test 2: Invalid steering prohibited type Version 2
        mac = '\x6e\xee\xb2\x94\x33\x6f'
        msg = '\x03' + mac + '\x05'
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)

        # Test 3: Valid steering prohibited messages Version 1
        for is_prohibited in [False, True]:
            # Abort steer to band with the given disabled band.
            mac = '\x6e\xee\xb2\x94\x33\x6f'
            msg = '\x03' + mac + chr(is_prohibited)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION1, False, msg)
            self.assertEquals(
                steerexec.SteeringProhibited._make(
                    (common.ether_ntoa(mac), is_prohibited)), payload)

            # Same as above but in big-endian (which makes no difference)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION1, True, msg)
            self.assertEquals(
                steerexec.SteeringProhibited._make(
                    (common.ether_ntoa(mac), is_prohibited)), payload)
コード例 #10
0
    def test_pre_assoc_steer(self):
        """Verify the parsing of the pre-association steer message."""
        mac = '\x94\x45\x8d\x13\xb7\x86'
        transaction = '\x30'
        channel_count = '\x01'
        channel1 = '\x0a'
        channel2 = '\xfe'
        # Test 1: Single channel
        msg = '\x00' + mac + transaction + channel_count + channel1
        payload = steerexec.unpack_payload_from_bytes(common.Version.VERSION2,
                                                      False, msg)
        self.assertEquals(
            steerexec.PreAssocSteer._make(
                (common.ether_ntoa(mac), 0x30, 1, [0x0a])), payload)

        # Same as above but in big-endian (which makes no difference)
        payload = steerexec.unpack_payload_from_bytes(common.Version.VERSION2,
                                                      True, msg)
        self.assertEquals(
            steerexec.PreAssocSteer._make(
                (common.ether_ntoa(mac), 0x30, 1, [0x0a])), payload)

        # Test 2: Two channels
        channel_count = '\x02'
        msg = '\x00' + mac + transaction + channel_count + channel1 + channel2
        payload = steerexec.unpack_payload_from_bytes(common.Version.VERSION2,
                                                      False, msg)
        self.assertEquals(
            steerexec.PreAssocSteer._make(
                (common.ether_ntoa(mac), 0x30, 2, [0x0a, 0xfe])), payload)

        # Test 3: Incorrect channel count raises an error
        msg = '\x00' + mac + transaction + 'x00' + channel1 + channel2
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)

        msg = '\x00' + mac + transaction + 'x03' + channel1 + channel2
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)
コード例 #11
0
    def test_interference_stats_msg(self):
        """Verify the parsing of the interference stats message"""
        # Test 1: Stats on a BSS on channel 36
        mac = '\x42\x62\x89\x67\x4d\xb4'
        msg = '\x04' + mac + '\xff\x24\x00\x20\x01\x02' + \
              '\x01\x02\x03\x04\x05\x06\x07\x08' + \
              '\x0a\x0b\x0c\x0d'

        payload = estimator.unpack_payload_from_bytes(common.Version.VERSION2,
                                                      False, msg)
        self.assertEquals(
            estimator.InterferenceStats._make(
                (common.ether_ntoa(mac), common.BSSInfo(255, 36, 0), 32, 513,
                 578437695752307201, 218893066)), payload)

        # Test 2: Similar but in big endian format (Tx rate changes)
        payload = estimator.unpack_payload_from_bytes(common.Version.VERSION2,
                                                      True, msg)
        self.assertEquals(
            estimator.InterferenceStats._make(
                (common.ether_ntoa(mac), common.BSSInfo(255, 36, 0), 32, 258,
                 72623859790382856, 168496141)), payload)
コード例 #12
0
    def test_non_serving_data_metrics_msg(self):
        """Verify the parsing of the non-serving data metrics message."""
        # Test 1: Measurement on a BSS on channel 6
        mac = '\x42\x62\x89\x67\x4d\xb4'
        msg = '\x01' + mac + '\xff\x06\x01' + \
              '\x50\x00\x00\x00\x42'
        payload = estimator.unpack_payload_from_bytes(common.Version.VERSION2,
                                                      False, msg)
        self.assertEquals(
            estimator.NonServingDataMetrics._make(
                (common.ether_ntoa(mac), common.BSSInfo(255, 6, 1), 80, 66)),
            payload)

        # Test 2: Similar but in big endian format
        msg = '\x01' + mac + '\x02\x24\x00' + \
              '\x00\x00\x00\x50\x42'
        payload = estimator.unpack_payload_from_bytes(common.Version.VERSION2,
                                                      True, msg)
        self.assertEquals(
            estimator.NonServingDataMetrics._make(
                (common.ether_ntoa(mac), common.BSSInfo(2, 36, 0), 80, 66)),
            payload)
コード例 #13
0
 def test_sta_interference_detected_msg(self):
     """Verify the parsing of the STA interference detected message."""
     # Test 1: Interference detected or not on a BSS on channel 11
     for big_endian in (False, True):
         for detected in (False, True):
             mac = '\x42\x62\x89\x67\x4d\xb4'
             msg = '\x02' + mac + '\xff\x0b\x01' + chr(detected)
             payload = estimator.unpack_payload_from_bytes(
                 common.Version.VERSION2, big_endian, msg)
             self.assertEquals(
                 estimator.STAInterferenceDetected._make(
                     (common.ether_ntoa(mac), common.BSSInfo(255, 11,
                                                             1), detected)),
                 payload)
コード例 #14
0
    def test_steering_unfriendly(self):
        """Verify the parsing of the steering unfriendly message."""
        # Test 1: Valid steering unfriendly messages
        for is_unfriendly in [False, True]:
            mac = '\x6e\xee\xb2\x94\x33\x6f'
            msg = '\x02' + mac + chr(is_unfriendly)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION1, False, msg)
            self.assertEquals(
                steerexec.SteeringUnfriendly._make(
                    (common.ether_ntoa(mac), is_unfriendly)), payload)

            # Same as above but in big-endian (which makes no difference)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION1, True, msg)
            self.assertEquals(
                steerexec.SteeringUnfriendly._make(
                    (common.ether_ntoa(mac), is_unfriendly)), payload)

        # Test 2: Valid steering unfriendly messages (v2)
        for is_unfriendly in [False, True]:
            mac = '\x6e\xee\xb2\x94\x33\x6f'
            msg = '\x02' + mac + chr(is_unfriendly) + '\x07\x00\x00\x00'
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION2, False, msg)
            self.assertEquals(
                steerexec.SteeringUnfriendly_v2._make(
                    (common.ether_ntoa(mac), is_unfriendly, 7)), payload)

            # Same as above but in big-endian
            msg = '\x02' + mac + chr(is_unfriendly) + '\x00\x00\x00\x07'
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION2, True, msg)
            self.assertEquals(
                steerexec.SteeringUnfriendly_v2._make(
                    (common.ether_ntoa(mac), is_unfriendly, 7)), payload)
コード例 #15
0
ファイル: test_common.py プロジェクト: lunatickochiya/ipq8074
    def test_ether_aton(self):
        """Test the function that packs an ethernet address."""
        self.assertRaises(ValueError, common.ether_aton,
                          'ff:c1:c4:62:22')  # too short
        self.assertRaises(ValueError, common.ether_aton,
                          'ff:c1:c4:62:22:53:53')  # too long
        self.assertRaises(ValueError, common.ether_aton,
                          'ff.c1.c4.62.22.53')  # wrong separator

        self.assertEquals('\xff\xc1\xc4\x62\x22\x53',
                          common.ether_aton('ff:c1:c4:62:22:53'))

        # Inverse of ether_ntoa
        self.assertEquals(
            '\xff\xc1\xc4\x62\x22\x53',
            common.ether_aton(common.ether_ntoa('\xff\xc1\xc4\x62\x22\x53')))
コード例 #16
0
def replace_mac_address_with_string(payload, attr_name='mac'):
    """Replace the MAC address in the tuple with a formatted string.

    Args:
        payload (tuple): tuple containing a message
        attr_name (str): string containing the name of the MAC address field

    Returns:
        tuple updated with the MAC address in attr_name (if present)
            replaced with a string representation
    """

    if hasattr(payload, attr_name):
        mac_addr = getattr(payload, attr_name)
        mac_addr = ether_ntoa(mac_addr)

        vals = {attr_name: mac_addr}
        payload = payload._replace(**vals)

    return payload
コード例 #17
0
    def test_unpack_msg(self):
        """Validate the top-level unpacking of messsages."""
        # Test 1: A wlanif message
        msg = '\x10\x18\x29\xc6\x09\x00\xd6\x73\x06\x00\x01\x00\x00\x16'
        header, payload = parser.unpack_msg(msg)
        self.assertEquals(
            common.Header._make((common.Version.VERSION1, False, 24, 0x9c629,
                                 0x673d6, common.ModuleID.WLANIF)), header)
        self.assertEquals(
            wlanif.RawChannelUtilization._make(
                (common.BAND_TYPE.BAND_24G, 22)), payload)

        # Test 2: A bandmon message
        msg = '\x11\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x01\x00\x37'
        header, payload = parser.unpack_msg(msg)
        self.assertEquals(
            common.Header._make(
                (common.Version.VERSION1, True, 162, 0x5177520e, 0x503d9,
                 common.ModuleID.BANDMON)), header)
        self.assertEquals(
            bandmon.Utilization_v1._make((common.BAND_TYPE.BAND_24G, 55)),
            payload)

        # Test 3: A stadb message
        mac = '\xb2\xdd\x69\xa1\xb3\xe3'
        msg = '\x10\xa2\x0e\x52\x77\x51\xd9\x03\x05\x00\x05\x00' + mac + \
              '\x00\x01\x01'
        header, payload = parser.unpack_msg(msg)
        self.assertEquals(
            common.Header._make((common.Version.VERSION1, False, 162,
                                 0x5177520e, 0x503d9, common.ModuleID.STADB)),
            header)
        self.assertEquals(
            stadb.AssociationUpdate._make(
                (common.ether_ntoa(mac), common.BAND_TYPE.BAND_24G, True,
                 True)), payload)

        # Test 4: A steerexec message
        mac = '\x6e\xee\xb2\x94\x33\x6f'
        msg = '\x11\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x02' + mac + '\x01'
        header, payload = parser.unpack_msg(msg)
        self.assertEquals(
            common.Header._make((common.Version.VERSION1, True, 24, 0x9c629,
                                 0x673d6, common.ModuleID.STEEREXEC)), header)
        self.assertEquals(
            steerexec.SteeringUnfriendly._make((common.ether_ntoa(mac), True)),
            payload)

        # Test 5: A diaglog message
        msg = '\x11\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x08\x00abc'
        header, payload = parser.unpack_msg(msg)
        self.assertEquals(
            common.Header._make(
                (common.Version.VERSION1, True, 162, 0x5177520e, 0x503d9,
                 common.ModuleID.DIAGLOG)), header)
        self.assertEquals(diaglog.StringMessage._make(('abc', )), payload)

        # Test 6: An estmiator message
        mac = '\x42\x62\x89\x67\x4d\xb4'
        msg = '\x20\x12\x60\x24\x87\x75\x15\x37\x00\x00\x09' + \
              '\x00' + mac + '\xff\x06\x01\x2d\x00\x00\x00\x08\x00\x00\x00' + \
              '\x50\x00\x00\x00\x42'
        header, payload = parser.unpack_msg(msg)
        self.assertEquals(
            common.Header._make(
                (common.Version.VERSION2, False, 18, 0x75872460, 0x3715,
                 common.ModuleID.ESTIMATOR)), header)
        self.assertEquals(
            estimator.ServingDataMetrics._make(
                (common.ether_ntoa(mac), common.BSSInfo(255, 6,
                                                        1), 45, 8, 80, 66)),
            payload)

        # Test 7: An unhandled module
        msg = '\x11\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x70\x12\x11\x22'
        self.assertRaises(ValueError, parser.unpack_msg, msg)
コード例 #18
0
    def test_msg_handler_multi_ap(self):
        """Test process_msgs when there are multiple AP registered.

        Make sure it will update model with the correct AP properly.
        Note that we only test valid messages here, since invalid messages will be
        handled by diagparser and not affect the logic here.
        """
        self._create_device_db()
        model = self._create_mock_model()
        handler = MsgHandler(model, diagparser, None)
        handler.add_ap(self._ap1, self._ap1_addr[0])
        # Each AP must have unique IP address
        self.assertRaises(ValueError, handler.add_ap, self._ap2,
                          self._ap1_addr[0])

        mac = '\x20\x02\xaf\xb7\x37\xa2'

        # Case 0: PostAssocSteer event, including 2 targets, should ignore remote BSS
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x05' + mac + \
              '\x51\x01\x01\xFF\x64\x00\x02\xFF\x06\x00\x00\x64\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac),
            start=True,
            assoc_vap=self._vap2,
            target_vaps=[self._vap1])
        model.update_station_steering_status.reset_mock()

        # Add second AP
        handler.add_ap(self._ap2, self._ap2_addr[0])

        # Case 1.1: Utilization on 2.4 GHz event for AP1 should update model
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x01\x06\x37'
        handler.process_msg(self._ap1_addr, msg)
        model.update_utilizations.assert_called_once_with(
            {
                'data': {
                    self._vap1.vap_id: 55
                },
                'type': 'average'
            }, self._ap1.ap_id)
        model.update_utilizations.reset_mock()

        # Case 1.2: RawChannelUtilization on 5 GHz event for AP2 should update model
        msg = '\x20\x18\x29\xc6\x09\x00\xd6\x73\x06\x00\x01\x00\x64\x16'
        handler.process_msg(self._ap2_addr, msg)
        model.update_utilizations.assert_called_once_with(
            {
                'data': {
                    self._vap4.vap_id: 22
                },
                'type': 'raw'
            }, self._ap2.ap_id)
        model.update_utilizations.reset_mock()

        # Case 2.1: RSSIUpdate on 5 GHz event on AP1 should update model
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x01' + mac + '\xFF\x64\x00\x10'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_rssi.assert_called_once_with(
            self._vap2.vap_id, common.ether_ntoa(mac), 16, self._ap1.ap_id)
        model.update_associated_station_rssi.reset_mock()

        # Case 2.2: RawRSSI on 2.4 GHz event on AP2 should udpate model
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x01\x01' + mac + '\xFF\x06\x00\x20'
        handler.process_msg(self._ap2_addr, msg)
        model.update_associated_station_rssi.assert_called_once_with(
            self._vap3.vap_id, common.ether_ntoa(mac), 32, self._ap2.ap_id)
        model.update_associated_station_rssi.reset_mock()

        # Case 3.1: PostAssocSteer event, including 2 targets, one from local,
        #           one from the other AP
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x05' + mac + \
              '\x51\x01\x01\xFF\x64\x00\x02\xFF\x06\x00\x00\x64\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac),
            start=True,
            assoc_vap=self._vap2,
            target_vaps=[self._vap1, self._vap4])
        model.update_station_steering_status.reset_mock()

        # Case 3.2: PostAssocSteer event, including 2 targets, one from the
        #           other AP, one from unknown AP, will ignore the unknown AP for now
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x05' + mac + \
              '\x51\x01\x01\xFF\x64\x00\x02\x00\x64\x00\x01\x64\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac),
            start=True,
            assoc_vap=self._vap2,
            target_vaps=[self._vap4])
        model.update_station_steering_status.reset_mock()

        # Case 4.1: Association on 5 GHz event should update model
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + \
              '\xFF\x64\x00\x01\x01\x01\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        # Will disassociate on both APs
        calls = model.del_associated_station.call_args_list
        self.assertEquals(2, len(calls))
        self.assertEquals(((common.ether_ntoa(mac), self._ap1.ap_id), ),
                          calls[0])
        self.assertEquals(((common.ether_ntoa(mac), self._ap2.ap_id), ),
                          calls[1])
        model.add_associated_station.assert_called_once_with(
            self._vap2.vap_id, common.ether_ntoa(mac), self._ap1.ap_id)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac), assoc_vap=self._vap2)
        model.update_associated_station_activity.assert_called_once_with(
            self._vap2.vap_id,
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            is_active=True)  # starts as active on association
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id,
            is_dual_band=True)  # mark as dual band
        model.del_associated_station.reset_mock()
        model.add_associated_station.reset_mock()
        model.update_station_steering_status.reset_mock()
        model.update_associated_station_activity.reset_mock()
        model.update_station_flags.reset_mock()

        # Case 4.2: Disassociation event should update model
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + \
              '\xFF\x64\x00\x00\x01\x01\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.del_associated_station.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac), assoc_vap=None, ap_id=self._ap1.ap_id)
        handler.process_msg(self._ap1_addr, msg)
        model.del_associated_station.reset_mock()
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.update_associated_station_activity.called)
        self.assert_(not model.update_station_flags.called)
        model.update_station_steering_status.reset_mock()

        # Case 5.1: Pollution state change on remote BSS
        msg = "\x20\x66\x14\x9e\x33\x57\x07\x4a\x05\x00\x09\x03" + mac + \
              "\x00\x06\x00\x01\x02"
        handler.process_msg(self._ap2_addr, msg)
        model.update_station_pollution_state.assert_called_once_with(
            common.ether_ntoa(mac), self._ap2.ap_id, self._vap1, True)
        model.update_station_pollution_state.reset_mock()

        # Case 5.2 Pollution state change on unknown remote BSS is ignored
        msg = "\x20\x66\x14\x9e\x33\x57\x07\x4a\x05\x00\x09\x03" + mac + \
              "\x01\x06\x00\x01\x02"
        handler.process_msg(self._ap2_addr, msg)
        self.assert_(not model.update_station_pollution_state.called)

        # Case 0: Message with unknown IP address should do nothing
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x01\x06\x37'
        handler.process_msg(self._unknown_addr, msg)
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x01\x01' + mac + '\xFF\x06\x00\x20'
        handler.process_msg(self._unknown_addr, msg)
        self.assert_(not model.update_utilizations.called)
        self.assert_(not model.update_associated_station_rssi.called)
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.del_associated_station.called)
コード例 #19
0
ファイル: steerexec.py プロジェクト: lunatickochiya/ipq8074
def unpack_payload_from_bytes(version, big_endian, buf):
    """Unpack the payload portion of the message provided.

    Args:
        version (int): the version number of the message
        big_endian (bool): whether the payload is encoded in big endian
            format or not
        buf (str): the entire payload to be unpacked

    Returns:
        the unpacked message as a namedtuple of the right type

    Raises:
        :class:`MessageMalformedError`: Unsupported message ID or band
    """
    if len(buf) == 0:
        raise MessageMalformedError("Message ID is missing")

    msg_id = ord(buf[0])

    band_attrs = None
    check_steer = False
    check_status = False
    if version == common.Version.VERSION1:
        if msg_id == MessageID.STEER_TO_BAND.value:
            unpacker = _SteerToBand
            constructor = SteerToBand
            band_attrs = [('assoc_band', True), ('target_band', False)]
        elif msg_id == MessageID.ABORT_STEER_TO_BAND.value:
            unpacker = _AbortSteerToBand
            constructor = AbortSteerToBand
            band_attrs = [('disabled_band', False)]
        elif msg_id == MessageID.STEERING_UNFRIENDLY.value:
            unpacker = _SteeringUnfriendly
            constructor = SteeringUnfriendly
        elif msg_id == MessageID.STEERING_PROHIBITED.value:
            unpacker = _SteeringProhibited
            constructor = SteeringProhibited
        else:
            raise MessageMalformedError("Unsupported message ID: %d" % msg_id)
    elif version == common.Version.VERSION2:
        if msg_id == MessageID.PRE_ASSOC_STEER.value:
            unpacker = _PreAssocSteer
            constructor = PreAssocSteer
        elif msg_id == MessageID.STEER_END.value:
            unpacker = _SteerEnd
            constructor = SteerEnd
            check_steer = True
            check_status = True
        elif msg_id == MessageID.STEERING_UNFRIENDLY.value:
            unpacker = _SteeringUnfriendlyBE_v2 if big_endian else _SteeringUnfriendlyLE_v2
            constructor = SteeringUnfriendly_v2
        elif msg_id == MessageID.STEERING_PROHIBITED.value:
            unpacker = _SteeringProhibited_v2
            constructor = SteeringProhibited_v2
        elif msg_id == MessageID.BTM_COMPLIANCE.value:
            unpacker = _BTMComplianceBE if big_endian else _BTMComplianceLE
            constructor = BTMCompliance
        elif msg_id == MessageID.POST_ASSOC_STEER.value:
            unpacker = _PostAssocSteer
            constructor = PostAssocSteer
            check_steer = True
        else:
            raise MessageMalformedError("Unsupported message ID: %d" % msg_id)
    else:
        raise MessageMalformedError("Invalid version number: %d" % version)

    if len(buf) < unpacker.size + 1:
        raise MessageMalformedError("Message too short: %d (need %d)" %
                                    (len(buf), unpacker.size + 1))

    if msg_id == MessageID.PRE_ASSOC_STEER.value and version == common.Version.VERSION2:
        fields = unpacker.unpack(buf[1:unpacker.size + 1])
        payload = constructor._make([common.ether_ntoa(fields[0])] +
                                    list(fields)[1:])
    elif msg_id == MessageID.POST_ASSOC_STEER.value and version == common.Version.VERSION2:
        # Variable length messages
        # First unpack the fixed size portion
        fields = unpacker.unpack(buf[1:unpacker.size + 1])
        fields = fields + (0, 0, 0)
        payload = constructor._make([common.ether_ntoa(fields[0])] +
                                    list(fields)[1:])
    else:
        fields = unpacker.unpack(buf[1:])
        payload = constructor._make([common.ether_ntoa(fields[0])] +
                                    list(fields)[1:])

    if (msg_id == MessageID.PRE_ASSOC_STEER.value
            and version == common.Version.VERSION2):
        payload = get_pre_assoc_channel_list(payload, buf, unpacker)

    elif (msg_id == MessageID.POST_ASSOC_STEER.value
          and version == common.Version.VERSION2):
        payload = get_post_assoc_candidates(payload, buf, unpacker)

        payload = check_reason_type(payload)

    if band_attrs is not None:
        for attr in band_attrs:
            payload = common.check_band(payload,
                                        allow_invalid=attr[1],
                                        attr_name=attr[0])

    if msg_id == MessageID.STEERING_PROHIBITED.value and version == common.Version.VERSION2:
        payload = check_steering_prohibit_type(payload)

    if msg_id == MessageID.BTM_COMPLIANCE.value:
        payload = check_btm_compliance_type(payload)

    if check_steer:
        payload = check_steer_type(payload)

    if check_status:
        payload = check_status_type(payload)

    return payload
コード例 #20
0
    def test_msg_handler_process_msgs_v2(self):
        """Test process_msgs function, make sure it will update model properly

        Note that we only test valid messages here, since invalid messages will be
        handled by diagparser and not affect the logic here.
        """
        self._create_device_db()
        model = self._create_mock_model()
        handler = MsgHandler(model, diagparser, None)
        handler.add_ap(self._ap1, self._ap1_addr[0])

        # Case 1.1: Utilization on 2.4 GHz event should update model
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x01\x06\x37'
        handler.process_msg(self._ap1_addr, msg)
        model.update_utilizations.assert_called_once_with(
            {
                'data': {
                    self._vap1.vap_id: 55
                },
                'type': 'average'
            }, self._ap1.ap_id)
        model.update_utilizations.reset_mock()

        # Case 1.2: RawChannelUtilization on 5 GHz event should update model
        msg = '\x20\x18\x29\xc6\x09\x00\xd6\x73\x06\x00\x01\x00\x64\x16'
        handler.process_msg(self._ap1_addr, msg)
        model.update_utilizations.assert_called_once_with(
            {
                'data': {
                    self._vap2.vap_id: 22
                },
                'type': 'raw'
            }, self._ap1.ap_id)
        model.update_utilizations.reset_mock()

        mac = '\x20\x02\xaf\xb7\x37\xa2'
        # Case 2.1: RSSIUpdate on 5 GHz event should update model
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x01' + mac + '\xFF\x64\x00\x10'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_rssi.assert_called_once_with(
            self._vap2.vap_id, common.ether_ntoa(mac), 16, self._ap1.ap_id)
        model.update_associated_station_rssi.reset_mock()

        # Case 2.2: RawRSSI on 2.4 GHz event should udpate model
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x01\x01' + mac + '\xFF\x06\x00\x20'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_rssi.assert_called_once_with(
            self._vap1.vap_id, common.ether_ntoa(mac), 32, self._ap1.ap_id)
        model.update_associated_station_rssi.reset_mock()

        # Case 3.1: Association on 5 GHz event should update model
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + \
              '\xFF\x64\x00\x01\x01\x01\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.del_associated_station.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id)
        model.add_associated_station.assert_called_once_with(
            self._vap2.vap_id, common.ether_ntoa(mac), self._ap1.ap_id)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac), assoc_vap=self._vap2)
        model.update_associated_station_activity.assert_called_once_with(
            self._vap2.vap_id,
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            is_active=True)  # starts as active on association
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id,
            is_dual_band=True)  # mark as dual band
        model.del_associated_station.reset_mock()
        model.add_associated_station.reset_mock()
        model.update_station_steering_status.reset_mock()
        model.update_associated_station_activity.reset_mock()
        model.update_station_flags.reset_mock()

        # Case 3.2: Disassociation event should update model
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + \
              '\xFF\x64\x00\x00\x01\x01\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.del_associated_station.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac), assoc_vap=None, ap_id=self._ap1.ap_id)
        handler.process_msg(self._ap1_addr, msg)
        model.del_associated_station.reset_mock()
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.update_associated_station_activity.called)
        self.assert_(not model.update_station_flags.called)
        model.update_station_steering_status.reset_mock()

        # Case 4: OverloadChange event should update model
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x00\x01\x64'
        handler.process_msg(self._ap1_addr, msg)
        model.update_overload_status.assert_called_once_with(
            {
                self._vap1.vap_id: False,
                self._vap2.vap_id: True
            }, self._ap1._ap_id)
        model.update_overload_status.reset_mock()

        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x00\x02\x06\x64'
        handler.process_msg(self._ap1_addr, msg)
        model.update_overload_status.assert_called_once_with(
            {
                self._vap1.vap_id: True,
                self._vap2.vap_id: True
            }, self._ap1._ap_id)
        model.update_overload_status.reset_mock()

        # Case 5: PostAssocSteer event
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x05' + mac + \
              '\x51\x01\x01\xFF\x64\x00\x01\xFF\x06\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac),
            start=True,
            assoc_vap=self._vap2,
            target_vaps=[self._vap1])
        model.update_station_steering_status.reset_mock()

        # Case 6a: SteerEnd event with a non-success
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x01' + mac + '\x51\x01\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac), abort=True)
        model.update_station_steering_status.reset_mock()

        # Case 6b: SteerEnd event with a success; should be ignored
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x01' + mac + '\x51\x01\x00'
        handler.process_msg(self._ap1_addr, msg)
        self.assert_(not model.update_station_steering_status.called)

        # Case 7: Serving data metrics event
        msg = '\x20\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x09\x00' + mac + \
              '\xff\x06\x01\x2d\x00\x00\x00\x08\x00\x00\x00\x50\x00\x00\x00\x42'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_data_metrics.assert_called_once_with(
            self._vap1.vap_id, common.ether_ntoa(mac), 45 + 8, 80, 66,
            self._ap1.ap_id)
        model.update_associated_station_data_metrics.reset_mock()

        # Case 8a: Activity update - active
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x02' + mac + '\xFF\x64\x00\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_activity.assert_called_once_with(
            self._vap2.vap_id,
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            is_active=True)
        model.update_associated_station_activity.reset_mock()

        # Case 8b: Activity update - idle
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x02' + mac + '\xFF\x64\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_activity.assert_called_once_with(
            self._vap2.vap_id,
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            is_active=False)
        model.update_associated_station_activity.reset_mock()

        # Case 9a: SteeringUnfriendly event - unfriendly
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x02' + mac + \
              '\x01\x00\x00\x00\x05'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, is_unfriendly=True)
        model.update_station_flags.reset_mock()

        # Case 9b: SteeringUnfriendly event - friendly
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x02' + mac + \
              '\x00\x00\x00\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, is_unfriendly=False)
        model.update_station_flags.reset_mock()

        # Case 10a: Dual band update - is dual band
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x03' + mac + '\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, is_dual_band=True)
        model.update_station_flags.reset_mock()

        # Case 10b: Dual band update - is not dual band
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x03' + mac + '\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, is_dual_band=False)
        model.update_station_flags.reset_mock()

        # Case 11a: Steering prohibited - long prohibit
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x03' + mac + '\x02'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            prohibit_type=SteeringProhibitType.PROHIBIT_LONG)
        model.update_station_flags.reset_mock()

        # Case 11b: Steering prohibited - short prohibit
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x03' + mac + '\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            prohibit_type=SteeringProhibitType.PROHIBIT_SHORT)
        model.update_station_flags.reset_mock()

        # Case 11c: Steering prohibited - no prohibit
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x03' + mac + '\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            prohibit_type=SteeringProhibitType.PROHIBIT_NONE)
        model.update_station_flags.reset_mock()

        # Case 12a: BTMCompliance - idle friendly
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x04' + mac + \
              '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            btm_compliance=BTMComplianceType.BTM_COMPLIANCE_IDLE,
            is_btm_unfriendly=False)
        model.update_station_flags.reset_mock()

        # Case 12b: BTMCompliance - active unfriendly but still BTM friendly
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x04' + mac + \
              '\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            btm_compliance=BTMComplianceType.BTM_COMPLIANCE_ACTIVE_UNFRIENDLY,
            is_btm_unfriendly=False)
        model.update_station_flags.reset_mock()

        # Case 12c: BTMCompliance - active unfriendly and not BTM friendly
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x04' + mac + \
              '\x01\x01\x00\x00\x00\x00\x00\x00\x00\x02'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            btm_compliance=BTMComplianceType.BTM_COMPLIANCE_ACTIVE_UNFRIENDLY,
            is_btm_unfriendly=True)
        model.update_station_flags.reset_mock()

        # Case 12d: BTMCompliance - active and BTM friendly
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x04' + mac + \
              '\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            btm_compliance=BTMComplianceType.BTM_COMPLIANCE_ACTIVE,
            is_btm_unfriendly=False)
        model.update_station_flags.reset_mock()

        # Case 13a: BlackoutChange - blackout true
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x02\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_steering_blackout_status.assert_called_once_with(
            True, self._ap1._ap_id)
        model.update_steering_blackout_status.reset_mock()

        # Case 13b: BlackoutChange - blackout false
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x02\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_steering_blackout_status.assert_called_once_with(
            False, self._ap1._ap_id)
        model.update_steering_blackout_status.reset_mock()

        # Case 14a: Pollution state change - polluted
        msg = "\x20\x66\x14\x9e\x33\x57\x07\x4a\x05\x00\x09\x03" + mac + \
              "\xff\x06\x00\x01\x02"
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_pollution_state.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, self._vap1, True)
        model.update_station_pollution_state.reset_mock()

        # Case 14b: Pollution state change - not polluted
        msg = "\x21\x66\x14\x9e\x33\x57\x07\x4a\x05\x00\x09\x03" + mac + \
              "\xff\x64\x00\x00\x02"
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_pollution_state.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, self._vap2, False)
        model.update_station_pollution_state.reset_mock()

        # Case 14c: Pollution state change from unknown BSS, ignore
        msg = "\x20\x66\x14\x9e\x33\x57\x07\x4a\x05\x00\x09\x03" + mac + \
              "\xff\x01\x00\x00\x02"
        handler.process_msg(self._ap1_addr, msg)
        self.assert_(not model.update_station_pollution_state.called)

        # Case 15: Other events should be ignored
        # Diaglog message
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x08\x00abc'
        handler.process_msg(self._ap1_addr, msg)
        self.assert_(not model.update_utilizations.called)
        self.assert_(not model.update_associated_station_rssi.called)
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.del_associated_station.called)
        self.assert_(not model.update_overload_status.called)
コード例 #21
0
    def test_msg_handler_process_msgs_v2_not_found(self):
        """Test process_msgs function, make sure it will update model properly

        Note that we only test valid messages here, since invalid messages will be
        handled by diagparser and not affect the logic here.
        """
        self._create_device_db()
        model = self._create_mock_model()
        handler = MsgHandler(model, diagparser, None)
        handler.add_ap(self._ap3, self._ap3_addr[0])

        # Case 1.1: Utilization on 2.4 GHz
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x01\x06\x37'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_utilizations.called)
        model.update_utilizations.reset_mock()

        # Case 1.2: RawChannelUtilization on 2.4 GHz
        msg = '\x20\x18\x29\xc6\x09\x00\xd6\x73\x06\x00\x01\x00\x06\x16'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_utilizations.called)
        model.update_utilizations.reset_mock()

        mac = '\x20\x02\xaf\xb7\x37\xa2'
        # Case 2.1: RSSIUpdate on 2.4 GHz
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x01' + mac + '\xFF\x06\x00\x10'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_associated_station_rssi.called)
        model.update_associated_station_rssi.reset_mock()

        # Case 2.2: RawRSSI on 2.4 GHz
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x01\x01' + mac + '\xFF\x06\x00\x20'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_associated_station_rssi.called)
        model.update_associated_station_rssi.reset_mock()

        # Case 3.1: Association on 5 GHz
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + \
              '\xFF\x06\x00\x01\x01\x01\x00\x00'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.del_associated_station.called)
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.update_station_steering_status.called)
        self.assert_(not model.update_associated_station_activity.called)
        self.assert_(not model.update_station_flags.called)
        model.del_associated_station.reset_mock()
        model.add_associated_station.reset_mock()
        model.update_station_steering_status.reset_mock()
        model.update_associated_station_activity.reset_mock()
        model.update_station_flags.reset_mock()

        # Case 3.2: Disassociation
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + \
              '\xFF\x06\x00\x00\x01\x01\x00\x00'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.del_associated_station.called)
        self.assert_(not model.update_station_steering_status.called)
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.update_associated_station_activity.called)
        self.assert_(not model.update_station_flags.called)
        model.del_associated_station.reset_mock()
        model.add_associated_station.reset_mock()
        model.update_station_steering_status.reset_mock()
        model.update_associated_station_activity.reset_mock()
        model.update_station_flags.reset_mock()

        # Case 4: OverloadChange event should update model
        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x00\x01\x06'
        handler.process_msg(self._ap3_addr, msg)
        model.update_overload_status.assert_called_once_with(
            {self._vap5.vap_id: False}, self._ap3._ap_id)
        model.update_overload_status.reset_mock()

        msg = '\x21\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x00\x02\x06\x64'
        handler.process_msg(self._ap3_addr, msg)
        model.update_overload_status.assert_called_once_with(
            {self._vap5.vap_id: True}, self._ap3._ap_id)
        model.update_overload_status.reset_mock()

        # Case 5a: PostAssocSteer event with assoc invalid
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x05' + mac + \
              '\x51\x01\x01\xFF\x06\x00\x01\xFF\x64\x00'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_station_steering_status.called)
        model.update_station_steering_status.reset_mock()

        # Case 5b: PostAssocSteer event with all targets invalid
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x05' + mac + \
              '\x51\x01\x01\xFF\x06\x00\x01\xFF\x0b\x00'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_station_steering_status.called)
        model.update_station_steering_status.reset_mock()

        # Case 5c: PostAssocSteer event with one target invalid
        msg = '\x21\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x05' + mac + \
              '\x51\x01\x01\xFF\x64\x00\x02\xFF\x0b\x00\xFF\x64\x00'
        handler.process_msg(self._ap3_addr, msg)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac),
            start=True,
            assoc_vap=self._vap5,
            target_vaps=[self._vap5])
        model.update_station_steering_status.reset_mock()

        # Case 6: Serving data metrics event
        msg = '\x20\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x09\x00' + mac + \
              '\xff\x06\x01\x2d\x00\x00\x00\x08\x00\x00\x00\x50\x00\x00\x00\x42'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_associated_station_data_metrics.called)
        model.update_associated_station_data_metrics.reset_mock()

        # Case 7a: Activity update - active
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x02' + mac + '\xFF\x06\x00\x01'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_associated_station_activity.called)
        model.update_associated_station_activity.reset_mock()

        # Case 7b: Activity update - idle
        msg = '\x20\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x02' + mac + '\xFF\x06\x00\x00'
        handler.process_msg(self._ap3_addr, msg)
        self.assert_(not model.update_associated_station_activity.called)
        model.update_associated_station_activity.reset_mock()
コード例 #22
0
    def test_msg_handler_process_msgs(self):
        """Test process_msgs function, make sure it will update model properly

        Note that we only test valid messages here, since invalid messages will be
        handled by diagparser and not affect the logic here.
        """
        self._create_device_db()
        model = self._create_mock_model()
        handler = MsgHandler(model, diagparser, None)

        mac = '\x20\x02\xaf\xb7\x37\xa2'

        # Case 0: Message from unknown IP address will be ignored
        msg = '\x11\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x01\x00\x37'
        handler.process_msg(self._ap1_addr, msg)
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x01' + mac + '\x01\x10'
        handler.process_msg(self._ap1_addr, msg)
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + '\x01\x01\x01'
        handler.process_msg(self._ap1_addr, msg)
        self.assert_(not model.update_utilizations.called)
        self.assert_(not model.update_associated_station_rssi.called)
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.del_associated_station.called)

        # Register AP1 with diaglog handler
        handler.add_ap(self._ap1, self._ap1_addr[0])

        # Case 1.1: Utilization on 2.4 GHz event should update model
        msg = '\x11\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x01\x00\x37'
        handler.process_msg(self._ap1_addr, msg)
        model.update_utilizations.assert_called_once_with(
            {
                'data': {
                    self._vap1.vap_id: 55
                },
                'type': 'average'
            }, self._ap1.ap_id)
        model.update_utilizations.reset_mock()

        # Case 1.2: RawChannelUtilization on 5 GHz event should update model
        msg = '\x10\x18\x29\xc6\x09\x00\xd6\x73\x06\x00\x01\x00\x01\x16'
        handler.process_msg(self._ap1_addr, msg)
        model.update_utilizations.assert_called_once_with(
            {
                'data': {
                    self._vap2.vap_id: 22
                },
                'type': 'raw'
            }, self._ap1.ap_id)
        model.update_utilizations.reset_mock()

        # Case 2.1: RSSIUpdate on 5 GHz event should update model
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x01' + mac + '\x01\x10'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_rssi.assert_called_once_with(
            self._vap2.vap_id, common.ether_ntoa(mac), 16, self._ap1.ap_id)
        model.update_associated_station_rssi.reset_mock()

        # Case 2.2: RawRSSI on 2.4 GHz event should udpate model
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x01\x01' + mac + '\x00\x20'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_rssi.assert_called_once_with(
            self._vap1.vap_id, common.ether_ntoa(mac), 32, self._ap1.ap_id)
        model.update_associated_station_rssi.reset_mock()

        # Case 3.1: Association on 5 GHz event should update model
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + '\x01\x01\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.del_associated_station.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id)
        model.add_associated_station.assert_called_once_with(
            self._vap2.vap_id, common.ether_ntoa(mac), self._ap1.ap_id)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac), assoc_band=self._vap2.band)
        model.update_associated_station_activity.assert_called_once_with(
            self._vap2.vap_id,
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            is_active=True)  # starts as active on association
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id,
            is_dual_band=True)  # mark as dual band
        model.del_associated_station.reset_mock()
        model.add_associated_station.reset_mock()
        model.update_associated_station_activity.reset_mock()
        model.update_station_steering_status.reset_mock()
        model.update_station_flags.reset_mock()

        # Case 3.2: Disassociation event should update model
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x00' + mac + '\x02\x00\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.del_associated_station.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac), assoc_band=BAND_TYPE.BAND_INVALID)
        model.del_associated_station.reset_mock()
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.update_associated_station_activity.called)
        self.assert_(not model.update_station_flags.called)
        model.update_station_steering_status.reset_mock()

        # Case 4: OverloadChange event should update model
        msg = '\x11\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x00\x03\x02'
        handler.process_msg(self._ap1_addr, msg)
        model.update_overload_status.assert_called_once_with(
            {
                self._vap1.vap_id: False,
                self._vap2.vap_id: True
            }, self._ap1._ap_id)
        model.update_overload_status.reset_mock()

        msg = '\x11\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x02\x00\x00\x03'
        handler.process_msg(self._ap1_addr, msg)
        model.update_overload_status.assert_called_once_with(
            {
                self._vap1.vap_id: True,
                self._vap2.vap_id: True
            }, self._ap1._ap_id)
        model.update_overload_status.reset_mock()

        # Case 5: SteerToBand event
        msg = '\x11\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x00' + mac + '\x01\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac),
            start=True,
            assoc_band=BAND_TYPE.BAND_5G,
            target_band=BAND_TYPE.BAND_24G)
        model.update_station_steering_status.reset_mock()

        # Case 6: AbortSteerToBand event
        msg = '\x11\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x01' + mac + '\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_steering_status.assert_called_once_with(
            common.ether_ntoa(mac), abort=True)
        model.update_station_steering_status.reset_mock()

        # Case 7a: ActivityUpdate with active
        # Activity update
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x02' + mac + '\x01\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_activity.assert_called_once_with(
            self._vap2.vap_id,
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            is_active=True)
        model.update_associated_station_activity.reset_mock()

        # Case 7b: ActivityUpdate with idle
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x02' + mac + '\x01\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_associated_station_activity.assert_called_once_with(
            self._vap2.vap_id,
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            is_active=False)
        model.update_associated_station_activity.reset_mock()

        # Case 8a: SteeringUnfriendly with marked as unfriendly
        msg = '\x11\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x02' + mac + '\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, is_unfriendly=True)
        model.update_station_flags.reset_mock()

        # Case 8b: SteeringUnfriendly with marked as friendly
        msg = '\x11\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x02' + mac + '\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, is_unfriendly=False)
        model.update_station_flags.reset_mock()

        # Case 9a: Dual band update - is dual band
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x03' + mac + '\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, is_dual_band=True)
        model.update_station_flags.reset_mock()

        # Case 9b: Dual band update - is not dual band
        msg = '\x10\x0b\x29\x1f\x10\x01\x96\x0f\x07\x00\x05\x03' + mac + '\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac), self._ap1.ap_id, is_dual_band=False)
        model.update_station_flags.reset_mock()

        # Case 10a: Steering prohibited - is prohibited
        msg = '\x11\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x03' + mac + '\x01'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            prohibit_type=SteeringProhibitType.PROHIBIT_LONG)
        model.update_station_flags.reset_mock()

        # Case 10b: Steering prohibited - is not prohibited
        msg = '\x11\x18\x00\x09\xc6\x29\x00\x06\x73\xd6\x06\x03' + mac + '\x00'
        handler.process_msg(self._ap1_addr, msg)
        model.update_station_flags.assert_called_once_with(
            common.ether_ntoa(mac),
            self._ap1.ap_id,
            prohibit_type=SteeringProhibitType.PROHIBIT_NONE)
        model.update_station_flags.reset_mock()

        # Case 11: Other messages are ignored
        # Diaglog message
        msg = '\x11\xa2\x51\x77\x52\x0e\x00\x05\x03\xd9\x08\x00abc'
        handler.process_msg(self._ap1_addr, msg)
        self.assert_(not model.update_utilizations.called)
        self.assert_(not model.update_associated_station_rssi.called)
        self.assert_(not model.add_associated_station.called)
        self.assert_(not model.del_associated_station.called)
        self.assert_(not model.update_overload_status.called)
コード例 #23
0
    def test_post_assoc_steer(self):
        """Verify the parsing of the post-association steer message."""
        test_cases = itertools.product([
            SteerType.STEER_TYPE_NONE, SteerType.STEER_TYPE_LEGACY,
            SteerType.STEER_TYPE_BTM_AND_BLACKLIST, SteerType.STEER_TYPE_BTM,
            SteerType.STEER_TYPE_BTM_AND_BLACKLIST_ACTIVE,
            SteerType.STEER_TYPE_BTM_ACTIVE,
            SteerType.STEER_TYPE_PREASSOCIATION, SteerType.STEER_TYPE_BTM_BE,
            SteerType.STEER_TYPE_BTM_BE_ACTIVE,
            SteerType.STEER_TYPE_BTM_BLACKLIST_BE,
            SteerType.STEER_TYPE_BTM_BLACKLIST_BE_ACTIVE,
            SteerType.STEER_TYPE_LEGACY_BE
        ], [
            SteerReasonType.REASON_USER, SteerReasonType.REASON_ACTIVE_UPGRADE,
            SteerReasonType.REASON_ACTIVE_DOWNGRADE_RATE,
            SteerReasonType.REASON_ACTIVE_DOWNGRADE_RSSI,
            SteerReasonType.REASON_IDLE_UPGRADE,
            SteerReasonType.REASON_IDLE_DOWNGRADE,
            SteerReasonType.REASON_ACTIVE_OFFLOAD,
            SteerReasonType.REASON_IDLE_OFFLOAD,
            SteerReasonType.REASON_AP_REQUEST,
            SteerReasonType.REASON_INTERFERENCE_AVOIDANCE,
            SteerReasonType.REASON_INVALID
        ])

        for test_case in test_cases:
            # Type of steering.
            mac = '\x94\x45\x8d\x13\xb7\x86'
            transaction = '\x10'
            assoc_ap = '\xff'
            assoc_channel = '\x0b'
            assoc_ess = '\x00'
            ap1 = '\xff'
            channel1 = '\x0a'
            ess1 = '\x00'
            msg = '\x05' + mac + transaction + chr(test_case[0].value) + \
                chr(test_case[1].value) + \
                assoc_ap + assoc_channel + assoc_ess + '\x01' + ap1 + channel1 + ess1
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION2, False, msg)
            self.assertEquals(
                steerexec.PostAssocSteer._make(
                    (common.ether_ntoa(mac), 0x10, test_case[0], test_case[1],
                     common.BSSInfo(0xFF, 0x0B,
                                    0), 1, [common.BSSInfo(0xFF, 0x0A, 0)])),
                payload)

            # Same as above but in big-endian (which makes no difference)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION2, True, msg)
            self.assertEquals(
                steerexec.PostAssocSteer._make(
                    (common.ether_ntoa(mac), 0x10, test_case[0], test_case[1],
                     common.BSSInfo(0xFF, 0x0B,
                                    0), 1, [common.BSSInfo(0xFF, 0x0A, 0)])),
                payload)

        # Test 2: Invalid steer type (Version 2)
        mac = '\x49\xcd\x30\xda\x0c\x4c'
        msg = '\x05' + mac + transaction + '\x0d' + '\x01' + \
              assoc_ap + assoc_channel + assoc_ess + '\x01' + ap1 + channel1 + ess1
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)

        # Test 3: Invalid steer reason (Version 2)
        mac = '\x49\xcd\x30\xda\x0c\x4c'
        msg = '\x05' + mac + transaction + '\x01' + '\x0d' + \
              assoc_ap + assoc_channel + assoc_ess + '\x01' + ap1 + channel1 + ess1
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)

        # Test 4: Two candidate BSSes
        ap2 = '\xff'
        channel2 = '\x0c'
        ess2 = '\x00'
        msg = '\x05' + mac + transaction + chr(test_case[0].value) + \
              chr(test_case[1].value) + \
              assoc_ap + assoc_channel + assoc_ess + '\x02' + ap1 + channel1 + ess1 + \
              ap2 + channel2 + ess2
        payload = steerexec.unpack_payload_from_bytes(common.Version.VERSION2,
                                                      False, msg)
        self.assertEquals(
            steerexec.PostAssocSteer._make(
                (common.ether_ntoa(mac), 0x10, test_case[0], test_case[1],
                 common.BSSInfo(0xFF, 0x0B, 0), 2, [
                     common.BSSInfo(0xFF, 0x0A, 0),
                     common.BSSInfo(0xFF, 0x0C, 0)
                 ])), payload)

        # Test 5: Can't be parsed with version 1
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION1, False, msg)

        # Test 6: Incorrect candidate count raises an error
        msg = '\x05' + mac + transaction + '\x01' + '\x01' + \
              assoc_ap + assoc_channel + assoc_ess + '\x00' + ap1 + channel1 + ess1 + \
              ap2 + channel2 + ess2
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)

        msg = '\x05' + mac + transaction + '\x01' + '\x01' + \
              assoc_ap + assoc_channel + assoc_ess + '\x03' + ap1 + channel1 + ess1 + \
              ap2 + channel2 + ess2
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)
コード例 #24
0
    def test_rssi_update(self):
        """Verify the parsing of the RSSI update message v1."""
        # Test 1: RSSI update on 2.4 GHz
        mac = '\x8a\x25\xf2\x83\x93\x85'
        msg = '\x01' + mac + '\x00\x17'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, False, msg)
        self.assertEquals(stadb.RSSIUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_24G, 23)),
            payload)

        # Same in big endian
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, True, msg)
        self.assertEquals(stadb.RSSIUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_24G, 23)),
            payload)

        # Test 2: RSSI update on 5 GHz
        mac = '\x32\x10\xbb\xf6\xa5\x35'
        msg = '\x01' + mac + '\x01\x12'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, False, msg)
        self.assertEquals(stadb.RSSIUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_5G, 18)),
            payload)

        # Same in big endian
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, True, msg)
        self.assertEquals(stadb.RSSIUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_5G, 18)),
            payload)

        # Test 3: RSSI update on invalid band is malformed
        mac = '\xff\x7e\x74\x17\x52\xa9'
        msg = '\x01' + mac + '\x02\x06'
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, False, msg)

        # Same in big endian
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, True, msg)

        # Test 4: RSSI update on invalid band is malformed
        mac = '\xab\xd6\xd1\xd0\xfd\x25'
        msg = '\x01' + mac + '\x03\x06'
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, False, msg)

        # Same in big endian
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, True, msg)

        """Verify the parsing of the RSSI update message v2."""
        # Test 1: RSSI update on channel 1
        mac = '\x8a\x25\xf2\x83\x93\x85'
        msg = '\x02' + mac + '\xff\x01\x00\x17'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, False, msg)
        self.assertEquals(stadb.RSSIUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0xFF, 1, 0), 23)),
            payload)

        # Same in big endian
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, True, msg)
        self.assertEquals(stadb.RSSIUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0xFF, 1, 0), 23)),
            payload)

        # Test 2: RSSI update on channel 100
        mac = '\x32\x10\xbb\xf6\xa5\x35'
        msg = '\x02' + mac + '\x00\x24\x01\x12'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, False, msg)
        self.assertEquals(stadb.RSSIUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0, 36, 1), 18)),
            payload)

        # Same in big endian
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, True, msg)
        self.assertEquals(stadb.RSSIUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0, 36, 1), 18)),
            payload)

        # Test 3: RSSI update with V2 header and V1 payload is malformed
        mac = '\x32\x10\xbb\xf6\xa5\x35'
        msg = '\x02' + mac + '\x01\x12'
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION2, False, msg)

        # Same in big endian
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION2, True, msg)
コード例 #25
0
    def test_activity_update(self):
        """Verify the parsing of the activity update message v1."""
        test_cases = itertools.product([BAND_TYPE.BAND_24G,
                                        BAND_TYPE.BAND_5G],
                                       [True, False])
        for test_case in test_cases:
            # Test with all combinations of band and activity change
            mac = '\xcd\x92\x1f\xe3\x84\x11'
            msg = '\x02' + mac + chr(test_case[0].value) + chr(test_case[1])
            payload = stadb.unpack_payload_from_bytes(
                common.Version.VERSION1, False, msg)
            self.assertEquals(stadb.ActivityUpdate._make(
                (common.ether_ntoa(mac), test_case[0], test_case[1])),
                payload)

            # Same as above but in big-endian (which makes no difference)
            payload = stadb.unpack_payload_from_bytes(
                common.Version.VERSION1, True, msg)
            self.assertEquals(stadb.ActivityUpdate._make(
                (common.ether_ntoa(mac), test_case[0], test_case[1])),
                payload)

        # Test 2: Activity update on a invalid band is malformed
        mac = '\x00\x66\x9a\x85\x7b\xd9'
        msg = '\x02' + mac + '\x02\x00'
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, False, msg)

        # Same in big endian
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, False, msg)

        # Test 3: Activity update on a bogus band is malformed
        mac = '\xbb\xb9\x21\xd4\xab\xd4'
        msg = '\x02' + mac + '\x03\x00'
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, False, msg)

        # Same in big endian
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, False, msg)

        """Verify the parsing of the activity update message v2."""
        for activity in [True, False]:
            # Test with all combinations of activity change
            mac = '\xcd\x92\x1f\xe3\x84\x11'
            msg = '\x02' + mac + '\xFF\x64\x00' + chr(activity)
            payload = stadb.unpack_payload_from_bytes(
                common.Version.VERSION2, False, msg)
            self.assertEquals(stadb.ActivityUpdate_v2._make(
                (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0),
                 activity)), payload)

            # Same as above but in big-endian (which makes no difference)
            payload = stadb.unpack_payload_from_bytes(
                common.Version.VERSION2, True, msg)
            self.assertEquals(stadb.ActivityUpdate_v2._make(
                (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0),
                 activity)), payload)
コード例 #26
0
    def test_association_update(self):
        """Verify the parsing of the association update message."""
        # Test 1: Associated on 2.4 GHz
        mac = '\xb2\xdd\x69\xa1\xb3\xe3'
        msg = '\x00' + mac + '\x00\x01\x00'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, False, msg)
        self.assertEquals(stadb.AssociationUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_24G, True, False)),
            payload)

        # Same as above but in big-endian (which makes no difference)
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, True, msg)
        self.assertEquals(stadb.AssociationUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_24G, True, False)),
            payload)

        # Test 2: Associated on 5 GHz
        mac = '\x67\xae\x3b\x86\xc3\x8e'
        msg = '\x00' + mac + '\x01\x01\x01'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, False, msg)
        self.assertEquals(stadb.AssociationUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_5G, True, True)),
            payload)

        # Same as above but in big endian
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, True, msg)
        self.assertEquals(stadb.AssociationUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_5G, True, True)),
            payload)

        # Test 3: Disassociated
        mac = '\x29\xed\x66\x8b\x16\x77'
        msg = '\x00' + mac + '\x02\x00\x00'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, False, msg)
        self.assertEquals(stadb.AssociationUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_INVALID, False,
             False)), payload)

        # Same as above but in big endian
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION1, True, msg)
        self.assertEquals(stadb.AssociationUpdate._make(
            (common.ether_ntoa(mac), BAND_TYPE.BAND_INVALID, False,
             False)), payload)

        # Test 3.1: A valid version 1 payload with a version 2 header is malformed
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION2, False, msg)

        # Same in big endian
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION2, True, msg)

        # Test 4: Association update on a bogus band is malformed
        mac = '\xfc\x91\x14\xc5\x3c\x7f'
        msg = '\x00' + mac + '\x03\x00\x01'
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, False, msg)

        # Same in big endian
        self.assertRaises(
            MessageMalformedError, stadb.unpack_payload_from_bytes,
            common.Version.VERSION1, True, msg)

        # Repeat above test with a version 2 message
        # Test 5: Associated on 2.4 GHz
        mac = '\xb2\xdd\x69\xa1\xb3\xe3'
        msg = '\x00' + mac + '\xFF\x0b\x00\x01\x01\x00\x01\x00'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, False, msg)
        self.assertEquals(stadb.AssociationUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0xFF, 11, 0),
             True, True, False, True, False)),
            payload)

        # Same as above but in big-endian (which makes no difference)
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, True, msg)
        self.assertEquals(stadb.AssociationUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0xFF, 11, 0),
             True, True, False, True, False)),
            payload)

        # Test 6: Associated on 5 GHz
        mac = '\x67\xae\x3b\x86\xc3\x8e'
        msg = '\x00' + mac + '\xFF\x64\x00\x01\x01\x01\x00\x01'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, False, msg)
        self.assertEquals(stadb.AssociationUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0),
             True, True, True, False, True)),
            payload)

        # Same as above but in big endian
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, True, msg)
        self.assertEquals(stadb.AssociationUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0),
             True, True, True, False, True)),
            payload)

        # Test 7: Disassociated
        mac = '\x29\xed\x66\x8b\x16\x77'
        msg = '\x00' + mac + '\xFF\x64\x00\x00\x00\x00\x00\x00'
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, False, msg)
        self.assertEquals(stadb.AssociationUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0),
             False, False, False, False, False)), payload)

        # Same as above but in big endian
        payload = stadb.unpack_payload_from_bytes(
            common.Version.VERSION2, True, msg)
        self.assertEquals(stadb.AssociationUpdate_v2._make(
            (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0),
             False, False, False, False, False)), payload)
コード例 #27
0
    def test_steer_end(self):
        """Verify the parsing of the steer end message."""
        test_cases = itertools.product([
            SteerType.STEER_TYPE_NONE, SteerType.STEER_TYPE_LEGACY,
            SteerType.STEER_TYPE_BTM_AND_BLACKLIST, SteerType.STEER_TYPE_BTM,
            SteerType.STEER_TYPE_BTM_AND_BLACKLIST_ACTIVE,
            SteerType.STEER_TYPE_BTM_ACTIVE,
            SteerType.STEER_TYPE_PREASSOCIATION, SteerType.STEER_TYPE_BTM_BE,
            SteerType.STEER_TYPE_BTM_BE_ACTIVE,
            SteerType.STEER_TYPE_BTM_BLACKLIST_BE,
            SteerType.STEER_TYPE_BTM_BLACKLIST_BE_ACTIVE,
            SteerType.STEER_TYPE_LEGACY_BE
        ], [
            SteerEndStatusType.STATUS_SUCCESS,
            SteerEndStatusType.STATUS_ABORT_AUTH_REJECT,
            SteerEndStatusType.STATUS_ABORT_LOW_RSSI,
            SteerEndStatusType.STATUS_ABORT_CHANGE_TARGET,
            SteerEndStatusType.STATUS_ABORT_USER,
            SteerEndStatusType.STATUS_BTM_REJECT,
            SteerEndStatusType.STATUS_BTM_RESPONSE_TIMEOUT,
            SteerEndStatusType.STATUS_ASSOC_TIMEOUT,
            SteerEndStatusType.STATUS_CHANNEL_CHANGE,
            SteerEndStatusType.STATUS_PREPARE_FAIL,
            SteerEndStatusType.STATUS_UNEXPECTED_BSS
        ])

        # Test 1: Valid steer end messages
        for test_case in test_cases:
            # Test all combinations for steer type and status.
            mac = '\x94\x45\x8d\x13\xb7\x86'
            transaction = '\x33'
            msg = '\x01' + mac + transaction + chr(test_case[0].value) + chr(
                test_case[1].value)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION2, False, msg)
            self.assertEquals(
                steerexec.SteerEnd._make((common.ether_ntoa(mac), 0x33,
                                          test_case[0], test_case[1])),
                payload)

            # Same as above but in big-endian (which makes no difference)
            payload = steerexec.unpack_payload_from_bytes(
                common.Version.VERSION2, True, msg)
            self.assertEquals(
                steerexec.SteerEnd._make((common.ether_ntoa(mac), 0x33,
                                          test_case[0], test_case[1])),
                payload)

        # Test 2: Invalid steer type
        mac = '\x49\xcd\x30\xda\x0c\x4c'
        msg = '\x01' + mac + transaction + '\x0d\x00'
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)

        # Test 3: Invalid status
        mac = '\x49\xcd\x30\xda\x0c\x4c'
        msg = '\x01' + mac + transaction + '\x01\x0c'
        self.assertRaises(MessageMalformedError,
                          steerexec.unpack_payload_from_bytes,
                          common.Version.VERSION2, False, msg)
コード例 #28
0
    def test_raw_rssi(self):
        """Verify the parsing of the RSSI message v1."""
        # Test 1: Measurement on 2.4 GHz
        mac = '\x42\x62\x89\x67\x4d\xb4'
        msg = '\x01' + mac + '\x00\x16'
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION1,
                                                   False, msg)
        self.assertEquals(
            wlanif.RawRSSI._make(
                (common.ether_ntoa(mac), BAND_TYPE.BAND_24G, 22)), payload)

        # Test 2: Similar but in big endian format (which makes no difference)
        msg = '\x01' + mac + '\x00\x25'
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION1,
                                                   True, msg)
        self.assertEquals(
            wlanif.RawRSSI._make(
                (common.ether_ntoa(mac), BAND_TYPE.BAND_24G, 37)), payload)

        # Test 3: RSSI measurement on 5 GHz now
        mac = '\xec\x40\xe4\xe7\xf5\xa5'
        msg = '\x01' + mac + '\x01\x50'
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION1,
                                                   False, msg)
        self.assertEquals(
            wlanif.RawRSSI._make(
                (common.ether_ntoa(mac), BAND_TYPE.BAND_5G, 80)), payload)

        # Test 4: Same in big endian
        msg = '\x01' + mac + '\x01\x47'
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION1,
                                                   True, msg)
        self.assertEquals(
            wlanif.RawRSSI._make(
                (common.ether_ntoa(mac), BAND_TYPE.BAND_5G, 71)), payload)

        # Test 5: The invalid enumerated band is rejected
        msg = '\x01' + mac + '\x02\x37'
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION1, False, msg)
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION1, True, msg)

        # Test 6: Band that is not even contained within the enum
        msg = '\x01' + mac + '\x03\x37'
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION1, False, msg)
        self.assertRaises(MessageMalformedError,
                          wlanif.unpack_payload_from_bytes,
                          common.Version.VERSION1, True, msg)
        """Verify the parsing of the RSSI message v2."""
        # Test 1: Measurement on APID = 0xFF, channel = 100, essId = 0
        msg = '\x01' + mac + '\xFF\x64\x00\x16'
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION2,
                                                   False, msg)
        self.assertEquals(
            wlanif.RawRSSI_v2._make(
                (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0), 22)),
            payload)

        # Test 2: Similar but in big endian format (which makes no difference)
        msg = '\x01' + mac + '\xFF\x64\x00\x16'
        payload = wlanif.unpack_payload_from_bytes(common.Version.VERSION2,
                                                   True, msg)
        self.assertEquals(
            wlanif.RawRSSI_v2._make(
                (common.ether_ntoa(mac), common.BSSInfo(0xFF, 100, 0), 22)),
            payload)