Ejemplo n.º 1
0
def _supported_id_numbers(socket, timeout, service_class, id_name, verbose):
    """ Check which Parameter IDs are supported by the vehicle

    Args:
        socket: is the ISOTPSocket, over which the OBD-Services communicate.
                the id 0x7df acts as a broadcast address for all obd-supporting ECUs.
        timeout: only required for the OBD Simulator, since it might tell it
                 supports a PID, while it actually doesn't and won't respond to this PID.
                 If this happens with a real ECU, it is an implementation error.
        service_class: specifies, which OBD-Service should be queried.
        id_name: describes the car domain (e.g.: mid = IDs in Motor Domain).
        verbose: specifies, whether the sr1()-method gives feedback or not.

    This method sends a query message via a ISOTPSocket, which will be responded by the ECUs with
    a message containing Bits, representing whether a PID is supported by the vehicle's protocol implementation or not.
    The first Message has the PID 0x00 and contains 32 Bits, which indicate by their index and value, which PIDs are
    supported.
    If  the PID 0x20 is supported, that means, there are more supported PIDs within the next 32 PIDs, which will result
    in a new query message being sent, that contains the next 32 Bits.
    There is a maximum of 256 possible PIDs.
    The supported PIDs will be returned as set.
    """

    supported_id_numbers = set()
    supported_prop = 'supported_' + id_name + 's'

    # ID 0x00 requests the first range of supported IDs in OBD
    supported_ids_req = OBD() / service_class(b'\x00')

    while supported_ids_req is not None:
        resp = socket.sr1(supported_ids_req, timeout=timeout, verbose=verbose)

        # If None, the device did not respond.
        # Usually only occurs, if device is off.
        if resp is None:
            break

        supported_ids_req = None

        all_supported_in_range = getattr(resp.data_records[0], supported_prop)

        for supported in all_supported_in_range:
            id_number = int(supported[-2:], 16)
            supported_id_numbers.add(id_number)

            # send a new query if the next PID range is supported
            if id_number % 0x20 == 0:
                supported_ids_req = OBD() / service_class(chb(id_number))

    return supported_id_numbers
Ejemplo n.º 2
0
def _scan_id_service(socket, timeout, service_class, id_numbers, verbose):
    """ Queries certain PIDs and stores their return value

    Args:
        socket: is the ISOTPSocket, over which the OBD-Services communicate.
                the id 0x7df acts as a broadcast address for all obd-supporting ECUs.
        timeout: only required for the OBD Simulator, since it might tell it
                 supports a PID, while it actually doesn't and won't respond to this PID.
                 If this happens with a real ECU, it is an implementation error.
        service_class: specifies, which OBD-Service should be queried.
        id_numbers: a set of PIDs, which should be queried by the method.
        verbose: specifies, whether the sr1()-method gives feedback or not.

    This method queries the specified id_numbers and stores their responses in a dictionary, which is then returned.
    """

    data = dict()

    for id_number in id_numbers:
        id_byte = chb(id_number)
        # assemble request packet
        pkt = OBD() / service_class(id_byte)
        resp = socket.sr1(pkt, timeout=timeout, verbose=verbose)

        if resp is not None:
            data[id_number] = bytes(resp)
    return data
Ejemplo n.º 3
0
class OBD_S0A_Enumerator(OBD_DTC_Enumerator):
    description = "Available DTCs in OBD service 10"
    request = OBD() / OBD_S0A()

    @staticmethod
    def get_table_entry(tup):
        _, _, res = tup
        label = OBD_Enumerator.get_label(
            res,
            positive_case=lambda: OBD_DTC_Enumerator.print_payload(res))
        return "Service 0A", "%d DTCs" % res.count, label
Ejemplo n.º 4
0
def _scan_dtc_service(socket, timeout, service_class, verbose):
    """ Queries Diagnostic Trouble Code Parameters and stores their return value

    Args:
        socket: is the ISOTPSocket, over which the OBD-Services communicate.
                the id 0x7df acts as a broadcast address for all obd-supporting ECUs.
        timeout: only required for the OBD Simulator, since it might tell it
                 supports a PID, while it actually doesn't and won't respond to this PID.
                 If this happens with a real ECU, it is an implementation error.
        service_class: specifies, which OBD-Service should be queried.
        verbose: specifies, whether the sr1()-method gives feedback or not.

    This method queries the specified Diagnostic Trouble Code Parameters and stores their responses in a dictionary,
    which is then returned.
    """

    req = OBD() / service_class()
    resp = socket.sr1(req, timeout=timeout, verbose=verbose)
    if resp is not None:
        return bytes(resp)
Ejemplo n.º 5
0
 def _get_initial_requests(self, **kwargs):
     # type: (Any) -> Iterable[Packet]
     scan_range = kwargs.pop(
         "scan_range", range(0x100))  # type: Iterable[int]  # noqa: E501
     return (OBD() / OBD_S09(iid=[x]) for x in scan_range)
Ejemplo n.º 6
0
 def _get_initial_requests(self, **kwargs):
     # type: (Any) -> Iterable[Packet]
     return [OBD() / OBD_S0A()]
Ejemplo n.º 7
0
 def get_pkts(self, p_range):
     return (OBD() / OBD_S09(iid=[x]) for x in p_range)
Ejemplo n.º 8
0
 def get_pkts(self, p_range):
     return (OBD() / OBD_S02(requests=[OBD_S02_Record(pid=[x])])
             for x in p_range)