Kernel level filtering

Issue #86 new
Alex Chambery created an issue

Hello,

I am hoping to set up some filtering so that I can monitor when one of 4 messages is sent on a CAN bus and then take action depending on which message is received. I have tried using the bus.recv method as suggested to another issue, but my CAN bus is very populated and I worry that this filtering is not efficient enough. I am hoping to implement kernel level filtering, but cannot find any good example code. Any help is greatly appreciated.

Comments (4)

  1. Alex Chambery reporter

    I see the following code has been suggested in a previous issue:

    #Filtered bus
    
    try:
        import can
        from can.interfaces.socketcan_constants import *   #CAN_RAW
        from can.interfaces.socketcan_ctypes import libc
    except ImportError:
        print '** python-CAN not supported **'
    
    import ctypes   
    
    class CANfilterStruct(ctypes.Structure):
        _fields_ = [("can_id", ctypes.c_uint32),
                    ("can_mask", ctypes.c_uint32)]
    
    class FilteredBus(can.interface.Bus):
    
        def __init__(self, channel=can.rc['channel'], receive_own_messages=False, *args, **kwargs):
    
            can.rc['interface'] = 'socketcan_ctypes'
            can.rc['channel'] = 'can0'
    
            super(FilteredBus, self).__init__()
    
            filterCount = 4
    
            canFilterArrayType = (CANfilterStruct * filterCount)
            canFilterArray = canFilterArrayType()
    
            canFilterArray[0].can_id = 0x200
            canFilterArray[0].can_mask = 0x7FE
    
            canFilterArray[1].can_id = 0x270
            canFilterArray[1].can_mask = 0x7FE
    
            canFilterArray[2].can_id = 0x100
            canFilterArray[2].can_mask = 0x7E0
    
            canFilterArray[3].can_id = 0x620
            canFilterArray[3].can_mask = 0x7F0
    
            response = libc.setsockopt(self.socket, SOL_CAN_RAW, CAN_RAW_FILTER, ctypes.byref(canFilterArray), ctypes.sizeof(canFilterArray))
    
            print response  
    

    I have placed this code in my python file and it compiles correctly after I update the ids and maskes for my purpose. However, I am unsure about how to implement this newly created "FilteredBus" class. When I try to implement it as:

    bus = can.interface.FilteredBus(channel="can0", bustype="socketcan")
    

    I get an error saying that the attribute does not exist

  2. Alex Chambery reporter

    I have attempted to use the bus.set_filters command, but I receive an error stating that I am trying to implement filters on an unsupported bus. The bus I am using is set as "socketcan" and will not seem to successfully initialize as any other type of bus (e.g "socketcan_native")

  3. Travis Travelstead

    Hello Alex,

    You should confirm which version of Python you are using. As Brian pointed out built in filtering can be used with Python 3.3 and above. This is the simplest way.

    The code you quoted above was a Python 2.7 workaround I helped with. For me to be able to help you please provide more of the exception information to help solve the problem. I have had this working before so I know it should work.

  4. Log in to comment