Ejemplo n.º 1
0
class FallbackSchema(colander.MappingSchema):
    """
    A schema validating the fields present in fallback options.
    """

    lacf = DefaultNode(colander.Boolean(), missing=True)
    ipf = DefaultNode(colander.Boolean(), missing=True)
Ejemplo n.º 2
0
class ValidWifiReportSchema(colander.MappingSchema, ValidatorNode):
    """A schema which validates the wifi specific fields in a report."""

    mac = MacNode(colander.String())

    age = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_AGE, constants.MAX_AGE),
    )

    channel = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_WIFI_CHANNEL,
                                 constants.MAX_WIFI_CHANNEL),
    )

    frequency = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_WIFI_FREQUENCY,
                                 constants.MAX_WIFI_FREQUENCY),
    )

    signal = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_WIFI_SIGNAL,
                                 constants.MAX_WIFI_SIGNAL),
    )

    snr = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_WIFI_SNR,
                                 constants.MAX_WIFI_SNR),
    )

    def deserialize(self, data):
        data = super(ValidWifiReportSchema, self).deserialize(data)
        if data and data is not colander.drop and data is not colander.null:
            channel = data.get("channel")
            frequency = data.get("frequency")
            if (frequency is None
                    and channel is not None) or (frequency is not None
                                                 and channel is None):
                # shallow copy
                data = dict(data)
                data["channel"], data["frequency"] = channel_frequency(
                    channel, frequency)

        return data
Ejemplo n.º 3
0
class ValidWifiSignalSchema(colander.MappingSchema, ValidatorNode):
    """
    A schema which validates the fields related to wifi signal
    strength and quality.
    """

    age = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(constants.MIN_AGE,
                                               constants.MAX_AGE))

    channel = DefaultNode(colander.Integer(),
                          missing=None,
                          validator=colander.Range(constants.MIN_WIFI_CHANNEL,
                                                   constants.MAX_WIFI_CHANNEL))

    signal = DefaultNode(colander.Integer(),
                         missing=None,
                         validator=colander.Range(constants.MIN_WIFI_SIGNAL,
                                                  constants.MAX_WIFI_SIGNAL))

    snr = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(0, 100))

    def deserialize(self, data):
        if data:
            channel = data.get('channel')
            channel = channel is not None and int(channel) or None

            if (channel is None or not (constants.MIN_WIFI_CHANNEL < channel <
                                        constants.MAX_WIFI_CHANNEL)):
                # shallow copy
                data = dict(data)

                # if no explicit channel was given, calculate
                freq = data.get('frequency', None)
                if freq is None:
                    freq = 0

                if 2411 < freq < 2473:
                    # 2.4 GHz band
                    data['channel'] = (freq - 2407) // 5
                elif freq == 2484:
                    data['channel'] = 14
                elif 5169 < freq < 5826:
                    # 5 GHz band
                    data['channel'] = (freq - 5000) // 5
                else:
                    data['channel'] = None

        return super(ValidWifiSignalSchema, self).deserialize(data)
Ejemplo n.º 4
0
class ValidCellKeySchema(ValidCellAreaKeySchema):

    cid = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_CID, constants.MAX_CID),
    )
    psc = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_PSC, constants.MAX_PSC),
    )

    def __init__(self, *args, **kw):
        super(ValidCellKeySchema, self).__init__(*args, **kw)
        self.radio_node = self.get("radio")

    def deserialize(self, data):
        if data:
            # shallow copy
            data = dict(data)
            # deserialize and validate radio field early
            data["radio"] = self.radio_node.deserialize(
                data.get("radio", colander.null)
            )

            # If the cell id > 65535 then it must be a WCDMA tower
            if (
                data["radio"] is Radio["gsm"]
                and data.get("cid") is not None
                and data.get("cid", 0) > constants.MAX_CID_GSM
            ):
                data["radio"] = Radio["wcdma"]

            if (
                data["radio"] is Radio["lte"]
                and data.get("psc") is not None
                and data.get("psc", 0) > constants.MAX_PSC_LTE
            ):
                data["psc"] = None

        return super(ValidCellKeySchema, self).deserialize(data)

    def validator(self, node, cstruct):
        super(ValidCellKeySchema, self).validator(node, cstruct)

        if (cstruct.get("lac") is None or cstruct.get("cid") is None) and cstruct.get(
            "psc"
        ) is None:
            raise colander.Invalid(node, ("Must have (LAC and CID) or PSC."))
class ValidBlueReportSchema(colander.MappingSchema, ValidatorNode):
    """A schema which validates the Bluetooth specific fields in a report."""

    mac = MacNode(colander.String())

    age = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(constants.MIN_AGE,
                                               constants.MAX_AGE))

    signal = DefaultNode(colander.Integer(),
                         missing=None,
                         validator=colander.Range(constants.MIN_BLUE_SIGNAL,
                                                  constants.MAX_BLUE_SIGNAL))
Ejemplo n.º 6
0
class ValidBlueSignalSchema(colander.MappingSchema, ValidatorNode):
    """
    A schema which validates the fields related to Bluetooth signal
    strength and quality.
    """

    age = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(constants.MIN_AGE,
                                               constants.MAX_AGE))

    signal = DefaultNode(colander.Integer(),
                         missing=None,
                         validator=colander.Range(constants.MIN_BLUE_SIGNAL,
                                                  constants.MAX_BLUE_SIGNAL))
class ValidBlueLookupSchema(colander.MappingSchema, ValidatorNode):
    """A schema which validates the fields in a Bluetooth lookup."""

    macAddress = MacNode(colander.String())
    name = DefaultNode(colander.String(), missing=None)

    age = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(
            constants.MIN_AGE, constants.MAX_AGE))

    signalStrength = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(
            constants.MIN_BLUE_SIGNAL, constants.MAX_BLUE_SIGNAL))
Ejemplo n.º 8
0
class ValidCellKeySchema(ValidCellAreaKeySchema):

    cid = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(constants.MIN_CID,
                                               constants.MAX_CID))
    psc = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(constants.MIN_PSC,
                                               constants.MAX_PSC))

    def __init__(self, *args, **kw):
        super(ValidCellKeySchema, self).__init__(*args, **kw)
        self.radio_node = self.get('radio')

    def deserialize(self, data):
        if data:
            # shallow copy
            data = dict(data)
            # deserialize and validate radio field early
            data['radio'] = self.radio_node.deserialize(
                data.get('radio', colander.null))

            # If the cell id > 65535 then it must be a WCDMA tower
            if (data['radio'] is Radio['gsm'] and data.get('cid') is not None
                    and data.get('cid', 0) > constants.MAX_CID_GSM):
                data['radio'] = Radio['wcdma']

            # Treat cid=65535 without a valid lac as an unspecified value
            if (data.get('lac') is None
                    and data.get('cid') == constants.MAX_CID_GSM):
                data['cid'] = None

        return super(ValidCellKeySchema, self).deserialize(data)

    def validator(self, node, cstruct):
        super(ValidCellKeySchema, self).validator(node, cstruct)

        if ((cstruct.get('lac') is None or cstruct.get('cid') is None)
                and cstruct.get('psc') is None):
            raise colander.Invalid(node, ('Must have (LAC and CID) or PSC.'))

        if (cstruct['radio'] is Radio['lte'] and cstruct.get('psc') is not None
                and cstruct.get('psc', 0) > constants.MAX_PSC_LTE):
            raise colander.Invalid(node, ('PSC is out of range for LTE.'))
Ejemplo n.º 9
0
class ValidCellLookupSchema(ValidCellAreaKeySchema, ValidCellSignalSchema):
    """A schema which validates the fields in a cell lookup."""

    cellId = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_CID, constants.MAX_CID),
    )
    primaryScramblingCode = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_PSC, constants.MAX_PSC),
    )

    def __init__(self, *args, **kw):
        super(ValidCellLookupSchema, self).__init__(*args, **kw)
        self.radio_node = self.get("radioType")

    def deserialize(self, data):
        if data:
            # shallow copy
            data = dict(data)
            # deserialize and validate radio field early
            data["radioType"] = self.radio_node.deserialize(
                data.get("radioType", colander.null))

            # If the cell id > 65535 then it must be a WCDMA tower
            if (data["radioType"] is Radio["gsm"]
                    and data.get("cellId") is not None
                    and data.get("cellId", 0) > constants.MAX_CID_GSM):
                data["radioType"] = Radio["wcdma"]

            if (data["radioType"] is Radio["lte"]
                    and data.get("primaryScramblingCode") is not None
                    and data.get("primaryScramblingCode",
                                 0) > constants.MAX_PSC_LTE):
                data["primaryScramblingCode"] = None

        return super(ValidCellLookupSchema, self).deserialize(data)

    def validator(self, node, cstruct):
        super(ValidCellLookupSchema, self).validator(node, cstruct)

        if cstruct["locationAreaCode"] is None or cstruct["cellId"] is None:
            raise colander.Invalid(node, ("LAC/CID are required in lookups."))
Ejemplo n.º 10
0
class ValidWifiLookupSchema(ValidWifiKeySchema):
    """A schema which validates the fields in a wifi lookup."""

    channel = colander.SchemaNode(
        colander.Integer(),
        missing=0,
        validator=colander.Range(
            constants.MIN_WIFI_CHANNEL, constants.MAX_WIFI_CHANNEL))
    signal = DefaultNode(
        colander.Integer(),
        missing=0,
        validator=colander.Range(
            constants.MIN_WIFI_SIGNAL, constants.MAX_WIFI_SIGNAL))
    snr = DefaultNode(
        colander.Integer(),
        missing=0,
        validator=colander.Range(0, 100))

    def deserialize(self, data):
        if data:
            channel = int(data.get('channel', 0))

            if not (constants.MIN_WIFI_CHANNEL
                    < channel
                    < constants.MAX_WIFI_CHANNEL):
                # if no explicit channel was given, calculate
                freq = data.get('frequency', 0)

                if 2411 < freq < 2473:
                    # 2.4 GHz band
                    data['channel'] = (freq - 2407) // 5

                elif 5169 < freq < 5826:
                    # 5 GHz band
                    data['channel'] = (freq - 5000) // 5

                else:
                    data['channel'] = self.fields['channel'].missing

            # map external name to internal
            if data.get('snr', None) is None:
                data['snr'] = data.get('signalToNoiseRatio', 0)

        return super(ValidWifiLookupSchema, self).deserialize(data)
class ValidCellAreaKeySchema(colander.MappingSchema, ValidatorNode):

    radio = DefaultNode(RadioType())
    mcc = colander.SchemaNode(colander.Integer())
    mnc = colander.SchemaNode(colander.Integer())
    lac = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(constants.MIN_LAC,
                                               constants.MAX_LAC))

    def validator(self, node, cstruct):
        super(ValidCellAreaKeySchema, self).validator(node, cstruct)

        if cstruct['mcc'] not in constants.ALL_VALID_MCCS:
            raise colander.Invalid(
                node, ('Check against the list of all known valid mccs'))

        if not (constants.MIN_MNC <= cstruct['mnc'] <= constants.MAX_MNC):
            raise colander.Invalid(node, ('MNC out of valid range.'))
Ejemplo n.º 12
0
class ValidCellLookupSchema(ValidCellKeySchema):
    """A schema which validates the fields in a cell lookup."""

    asu = DefaultNode(colander.Integer(),
                      missing=-1,
                      validator=colander.Range(0, 97))
    signal = DefaultNode(colander.Integer(),
                         missing=0,
                         validator=colander.Range(-150, -1))
    ta = DefaultNode(colander.Integer(),
                     missing=0,
                     validator=colander.Range(0, 63))

    def deserialize(self, data):
        if data:
            # Sometimes the asu and signal fields are swapped
            if data.get('asu', 0) < -1 and data.get('signal', None) == 0:
                data['signal'] = data['asu']
                data['asu'] = self.fields['asu'].missing
        return super(ValidCellLookupSchema, self).deserialize(data)
Ejemplo n.º 13
0
class ValidCellAreaKeySchema(colander.MappingSchema, ValidatorNode):

    radioType = DefaultNode(RadioType())
    mobileCountryCode = colander.SchemaNode(colander.Integer())
    mobileNetworkCode = colander.SchemaNode(colander.Integer())
    locationAreaCode = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_LAC, constants.MAX_LAC),
    )

    def validator(self, node, cstruct):
        super(ValidCellAreaKeySchema, self).validator(node, cstruct)

        if cstruct["mobileCountryCode"] not in constants.ALL_VALID_MCCS:
            raise colander.Invalid(
                node, ("Check against the list of all known valid mccs"))

        if not (constants.MIN_MNC <= cstruct["mobileNetworkCode"] <=
                constants.MAX_MNC):
            raise colander.Invalid(node, ("MNC out of valid range."))
Ejemplo n.º 14
0
class ValidCellAreaKeySchema(FieldSchema, CopyingSchema):
    """A schema which validates the fields present in a cell area key."""

    radio = RadioNode(RadioType())
    mcc = colander.SchemaNode(colander.Integer(),
                              validator=colander.Range(1, 999))
    mnc = colander.SchemaNode(colander.Integer(),
                              validator=colander.Range(0, 32767))
    lac = DefaultNode(colander.Integer(),
                      missing=0,
                      validator=colander.Range(constants.MIN_LAC,
                                               constants.MAX_LAC_ALL))
Ejemplo n.º 15
0
class ValidReportSchema(ValidPositionSchema):
    """A schema which validates the fields present in a report."""

    accuracy = DefaultNode(
        colander.Float(), missing=0, validator=colander.Range(
            0, constants.MAX_ACCURACY))
    altitude = DefaultNode(
        colander.Float(), missing=0, validator=colander.Range(
            constants.MIN_ALTITUDE, constants.MAX_ALTITUDE))
    altitude_accuracy = DefaultNode(
        colander.Float(), missing=0, validator=colander.Range(
            0, constants.MAX_ALTITUDE_ACCURACY))
    heading = DefaultNode(
        colander.Float(), missing=-1, validator=colander.Range(
            0, constants.MAX_HEADING))
    speed = DefaultNode(
        colander.Float(), missing=-1, validator=colander.Range(
            0, constants.MAX_SPEED))
    report_id = ReportIDNode(UUIDType())
    created = colander.SchemaNode(DateTimeFromString(), missing=None)
    time = RoundToMonthDateNode(DateTimeFromString(), missing=None)
Ejemplo n.º 16
0
class ValidReportSchema(colander.MappingSchema, ValidatorNode):
    """A schema which validates the fields present in a report."""

    lat = colander.SchemaNode(colander.Float(),
                              missing=None,
                              validator=colander.Range(constants.MIN_LAT,
                                                       constants.MAX_LAT))
    lon = colander.SchemaNode(colander.Float(),
                              missing=None,
                              validator=colander.Range(constants.MIN_LON,
                                                       constants.MAX_LON))
    accuracy = DefaultNode(colander.Float(),
                           missing=None,
                           validator=colander.Range(0.0,
                                                    constants.MAX_ACCURACY))
    altitude = DefaultNode(colander.Float(),
                           missing=None,
                           validator=colander.Range(constants.MIN_ALTITUDE,
                                                    constants.MAX_ALTITUDE))
    altitude_accuracy = DefaultNode(colander.Float(),
                                    missing=None,
                                    validator=colander.Range(
                                        0.0, constants.MAX_ALTITUDE_ACCURACY))
    heading = DefaultNode(colander.Float(),
                          missing=None,
                          validator=colander.Range(0.0, constants.MAX_HEADING))
    speed = DefaultNode(colander.Float(),
                        missing=None,
                        validator=colander.Range(0.0, constants.MAX_SPEED))

    def validator(self, node, cstruct):
        super(ValidReportSchema, self).validator(node, cstruct)
        for field in ('lat', 'lon'):
            if (cstruct[field] is None
                    or cstruct[field] is colander.null):  # pragma: no cover
                raise colander.Invalid(node, 'Report %s is required.' % field)

        if not GEOCODER.any_region(cstruct['lat'], cstruct['lon']):
            raise colander.Invalid(node, ('Lat/lon must be inside a region.'))
Ejemplo n.º 17
0
class ValidCellSignalSchema(colander.MappingSchema, ValidatorNode):

    asu = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(0, 97))
    signal = DefaultNode(colander.Integer(),
                         missing=None,
                         validator=colander.Range(-150, -1))
    ta = DefaultNode(colander.Integer(),
                     missing=None,
                     validator=colander.Range(0, 63))

    def deserialize(self, data):
        if data:
            # Sometimes the asu and signal fields are swapped
            if (data.get('asu') is not None and data.get('asu', 0) < -1
                    and data.get('signal', None) == 0):
                # shallow copy
                data = dict(data)
                data['signal'] = data['asu']
                data['asu'] = None
        return super(ValidCellSignalSchema, self).deserialize(data)
class ValidWifiLookupSchema(colander.MappingSchema, ValidatorNode):
    """A schema which validates the fields in a WiFi lookup."""

    macAddress = MacNode(colander.String())
    ssid = DefaultNode(colander.String(), missing=None)

    age = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(
            constants.MIN_AGE, constants.MAX_AGE))

    channel = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(
            constants.MIN_WIFI_CHANNEL, constants.MAX_WIFI_CHANNEL))

    frequency = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(
            constants.MIN_WIFI_FREQUENCY, constants.MAX_WIFI_FREQUENCY))

    signalStrength = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(
            constants.MIN_WIFI_SIGNAL, constants.MAX_WIFI_SIGNAL))

    signalToNoiseRatio = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(
            constants.MIN_WIFI_SNR, constants.MAX_WIFI_SNR))

    def deserialize(self, data):
        data = super(ValidWifiLookupSchema, self).deserialize(data)
        if (data and data is not colander.drop and data is not colander.null):
            channel = data.get('channel')
            frequency = data.get('frequency')
            if ((frequency is None and channel is not None) or
                    (frequency is not None and channel is None)):
                # shallow copy
                data = dict(data)
                data['channel'], data['frequency'] = channel_frequency(
                    channel, frequency)

        return data
class ValidCellReportSchema(ValidCellKeySchema):
    """A schema which validates the cell specific fields in a report."""

    age = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(constants.MIN_AGE,
                                               constants.MAX_AGE))

    asu = DefaultNode(colander.Integer(),
                      missing=None,
                      validator=colander.Range(
                          min(constants.MIN_CELL_ASU.values()),
                          max(constants.MAX_CELL_ASU.values())))

    signal = DefaultNode(colander.Integer(),
                         missing=None,
                         validator=colander.Range(
                             min(constants.MIN_CELL_SIGNAL.values()),
                             max(constants.MAX_CELL_SIGNAL.values())))

    ta = DefaultNode(colander.Integer(),
                     missing=None,
                     validator=colander.Range(constants.MIN_CELL_TA,
                                              constants.MAX_CELL_TA))

    def _signal_from_asu(self, radio, value):
        if radio is Radio.gsm:
            return (value * 2) - 113
        if radio is Radio.wcdma:
            return value - 116
        if radio is Radio.lte:
            return value - 140

    def deserialize(self, data):
        if data:
            # Sometimes the asu and signal fields are swapped
            if (data.get('asu') is not None and data.get('asu', 0) < -5 and
                (data.get('signal') is None or data.get('signal', 0) >= 0)):
                # shallow copy
                data = dict(data)
                data['signal'] = data['asu']
                data['asu'] = None

        data = super(ValidCellReportSchema, self).deserialize(data)

        if isinstance(data.get('radio'), Radio):
            radio = data['radio']

            # Radio type specific checks for ASU field
            if data.get('asu') is not None:
                if not (constants.MIN_CELL_ASU[radio] <= data['asu'] <=
                        constants.MAX_CELL_ASU[radio]):
                    data = dict(data)
                    data['asu'] = None

            # Radio type specific checks for signal field
            if data.get('signal') is not None:
                if not (constants.MIN_CELL_SIGNAL[radio] <= data['signal'] <=
                        constants.MAX_CELL_SIGNAL[radio]):
                    data = dict(data)
                    data['signal'] = None

            # Radio type specific checks for TA field
            if data.get('ta') is not None and radio is Radio.wcdma:
                data = dict(data)
                data['ta'] = None

            # Calculate signal from ASU field
            if data.get('asu') is not None and data.get('signal') is None:
                if (constants.MIN_CELL_ASU[radio] <= data['asu'] <=
                        constants.MAX_CELL_ASU[radio]):
                    data = dict(data)
                    data['signal'] = self._signal_from_asu(radio, data['asu'])

        return data

    def validator(self, node, cstruct):
        super(ValidCellReportSchema, self).validator(node, cstruct)
        for field in ('radio', 'mcc', 'mnc', 'lac', 'cid'):
            if (cstruct[field] is None or cstruct[field] is colander.null):
                raise colander.Invalid(node, 'Cell %s is required.' % field)
Ejemplo n.º 20
0
class ValidBlueLookupSchema(ValidBlueSignalSchema):
    """A schema which validates the fields in a Bluetooth lookup."""

    mac = MacNode(colander.String())
    name = DefaultNode(colander.String(), missing=None)
Ejemplo n.º 21
0
class ValidCellKeySchema(ValidCellAreaKeySchema):
    """A schema which validates the fields present in a cell key."""

    cid = DefaultNode(colander.Integer(),
                      missing=0,
                      validator=colander.Range(constants.MIN_CID,
                                               constants.MAX_CID_ALL))
    psc = DefaultNode(colander.Integer(),
                      missing=-1,
                      validator=colander.Range(0, 512))

    def deserialize(self, data):
        if data:
            # deserialize and validate radio field early
            radio_node = self.fields['radio']
            radio = radio_node.deserialize(data['radio'])
            if radio_node.validator(radio_node, radio):
                data['radio'] = radio

            # If the cell id >= 65536 then it must be a umts tower
            if (data.get('cid', 0) >= 65536 and data['radio'] == Radio.gsm):
                data['radio'] = Radio.umts

            # Treat cid=65535 without a valid lac as an unspecified value
            if (self.is_missing(data, 'lac')
                    and data.get('cid', None) == 65535):
                data['cid'] = self.fields['cid'].missing

        return super(ValidCellKeySchema, self).deserialize(data)

    def validator(self, schema, data):
        lac_missing = self.is_missing(data, 'lac')
        cid_missing = self.is_missing(data, 'cid')

        if data['mcc'] not in constants.ALL_VALID_MCCS:
            raise colander.Invalid(
                schema, ('Check against the list of all known valid mccs'))

        if (data['radio'] == Radio.cdma and (lac_missing or cid_missing)):
            raise colander.Invalid(
                schema,
                ('Skip CDMA towers missing lac or cid '
                 '(no psc on CDMA exists to backfill using inference)'))

        if data['radio'] in Radio._gsm_family() and data['mnc'] > 999:
            raise colander.Invalid(
                schema, ('Skip GSM/LTE/UMTS towers with an invalid MNC'))

        if ((lac_missing or cid_missing) and self.is_missing(data, 'psc')):
            raise colander.Invalid(schema,
                                   ('Must have (lac and cid) or '
                                    'psc (psc-only to use in backfill)'))

        if (data['radio'] == Radio.cdma
                and data['cid'] > constants.MAX_CID_CDMA):
            raise colander.Invalid(schema, ('CID is out of range for CDMA.'))

        if (data['radio'] == Radio.lte
                and data['cid'] > constants.MAX_CID_LTE):
            raise colander.Invalid(schema, ('CID is out of range for LTE.'))

        if (data['radio'] in Radio._gsm_family()
                and data['lac'] > constants.MAX_LAC_GSM_UMTS_LTE):
            raise colander.Invalid(schema,
                                   ('LAC is out of range for GSM/UMTS/LTE.'))
Ejemplo n.º 22
0
class ValidReportSchema(colander.MappingSchema, ValidatorNode):
    """A schema which validates the fields present in a report."""

    lat = colander.SchemaNode(
        colander.Float(),
        missing=None,
        validator=colander.Range(constants.MIN_LAT, constants.MAX_LAT),
    )
    lon = colander.SchemaNode(
        colander.Float(),
        missing=None,
        validator=colander.Range(constants.MIN_LON, constants.MAX_LON),
    )
    accuracy = DefaultNode(
        colander.Float(),
        missing=None,
        validator=colander.Range(constants.MIN_ACCURACY,
                                 constants.MAX_ACCURACY),
    )
    altitude = DefaultNode(
        colander.Float(),
        missing=None,
        validator=colander.Range(constants.MIN_ALTITUDE,
                                 constants.MAX_ALTITUDE),
    )
    altitude_accuracy = DefaultNode(
        colander.Float(),
        missing=None,
        validator=colander.Range(constants.MIN_ALTITUDE_ACCURACY,
                                 constants.MAX_ALTITUDE_ACCURACY),
    )
    heading = DefaultNode(
        colander.Float(),
        missing=None,
        validator=colander.Range(constants.MIN_HEADING, constants.MAX_HEADING),
    )
    pressure = DefaultNode(
        colander.Float(),
        missing=None,
        validator=colander.Range(constants.MIN_PRESSURE,
                                 constants.MAX_PRESSURE),
    )
    source = ReportSourceNode(ReportSourceType(), missing=None)
    speed = DefaultNode(
        colander.Float(),
        missing=None,
        validator=colander.Range(constants.MIN_SPEED, constants.MAX_SPEED),
    )
    timestamp = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_TIMESTAMP,
                                 constants.MAX_TIMESTAMP),
    )

    def validator(self, node, cstruct):
        super(ValidReportSchema, self).validator(node, cstruct)
        for field in ("lat", "lon"):
            if cstruct[field] is None or cstruct[field] is colander.null:
                raise colander.Invalid(node, "Report %s is required." % field)

        if not GEOCODER.any_region(cstruct["lat"], cstruct["lon"]):
            raise colander.Invalid(node, "Lat/lon must be inside a region.")
Ejemplo n.º 23
0
class ValidCellSignalSchema(colander.MappingSchema, ValidatorNode):

    age = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_AGE, constants.MAX_AGE),
    )

    asu = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(min(constants.MIN_CELL_ASU.values()),
                                 max(constants.MAX_CELL_ASU.values())),
    )

    signalStrength = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(
            min(constants.MIN_CELL_SIGNAL.values()),
            max(constants.MAX_CELL_SIGNAL.values()),
        ),
    )

    timingAdvance = DefaultNode(
        colander.Integer(),
        missing=None,
        validator=colander.Range(constants.MIN_CELL_TA, constants.MAX_CELL_TA),
    )

    def _signal_from_asu(self, radio, value):
        if radio is Radio.gsm:
            return (value * 2) - 113
        if radio is Radio.wcdma:
            return value - 116
        if radio is Radio.lte:
            return value - 140

    def deserialize(self, data):
        if data:
            # Sometimes the asu and signal fields are swapped
            if (data.get("asu") is not None and data.get("asu", 0) < -5
                    and (data.get("signalStrength") is None
                         or data.get("signalStrength", 0) >= 0)):
                # shallow copy
                data = dict(data)
                data["signalStrength"] = data["asu"]
                data["asu"] = None

        data = super(ValidCellSignalSchema, self).deserialize(data)

        if isinstance(data.get("radioType"), Radio):
            radio = data["radioType"]

            # Radio type specific checks for ASU field
            if data.get("asu") is not None:
                if not (constants.MIN_CELL_ASU[radio] <= data["asu"] <=
                        constants.MAX_CELL_ASU[radio]):
                    data = dict(data)
                    data["asu"] = None

            # Radio type specific checks for signal field
            if data.get("signalStrength") is not None:
                if not (constants.MIN_CELL_SIGNAL[radio] <=
                        data["signalStrength"] <=
                        constants.MAX_CELL_SIGNAL[radio]):
                    data = dict(data)
                    data["signalStrength"] = None

            # Radio type specific checks for TA field
            if data.get("timingAdvance") is not None and radio is Radio.wcdma:
                data = dict(data)
                data["timingAdvance"] = None

            # Calculate signal from ASU field
            if data.get(
                    "asu") is not None and data.get("signalStrength") is None:
                if (constants.MIN_CELL_ASU[radio] <= data["asu"] <=
                        constants.MAX_CELL_ASU[radio]):
                    data = dict(data)
                    data["signalStrength"] = self._signal_from_asu(
                        radio, data["asu"])

        return data
Ejemplo n.º 24
0
class ValidWifiLookupSchema(ValidWifiSignalSchema):
    """A schema which validates the fields in a WiFi lookup."""

    mac = MacNode(colander.String())
    ssid = DefaultNode(colander.String(), missing=None)