Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M2 Mac - list_resources() not returning available TCPIP instrument #403

Open
dstrande opened this issue Nov 27, 2023 · 22 comments
Open

M2 Mac - list_resources() not returning available TCPIP instrument #403

dstrande opened this issue Nov 27, 2023 · 22 comments

Comments

@dstrande
Copy link

On an M2 Mac, rm.list_resources() isn't returning an available TCPIP instrument.

rm = pyvisa.ResourceManager("@py")
print(rm.list_resources())

inst = rm.open_resource("TCPIP::169.254.4.179::INSTR")
print(inst.query("*IDN?"))

Returns:

()
KEITHLEY INSTRUMENTS,MODEL 2450,04505775,1.7.12b

Showing the instrument will connect but fails to show for list_resources.

I tried doing a bit of debugging but not totally sure what I was doing:

resp = pmap.recv_port((vxi11.DEVICE_CORE_PROG, vxi11.DEVICE_CORE_VERS, rpc.IPPROTO_TCP, 0))

seems to fail to return any response on Mac but succeeds on Windows.

To Reproduce

Steps to reproduce the behavior:

  1. Connect instrument withFind IP address of your instrument
  2. Use code above with a ARM Mac (?) replacing IP address with your instrument's

Output of pyvisa-info

Machine Details:
   Platform ID:    macOS-13.5-arm64-arm-64bit
   Processor:      arm

Python:
   Implementation: CPython
   Executable:     /***
   Version:        3.11.6
   Compiler:       Clang 15.0.7 
   Architecture:   ('arm', 64)
   Build:          Oct  3 2023 10:37:07 (#main)
   Unicode:        UCS4

PyVISA Version: 1.14.1

Backends:
   ivi:
      Version: 1.14.1 (bundled with PyVISA)
      Binary library: Not found
   py:
      Version: 0.7.1
      TCPIP INSTR: Available 
         Resource discovery:
         - VXI-11: ok
         - hislip: ok
      TCPIP SOCKET: Available 
      ASRL INSTR:
         Please install PySerial (>=3.0) to use this resource type.
         No module named 'serial'
      USB INSTR:
         Please install PyUSB to use this resource type.
         No module named 'usb'
      USB RAW:
         Please install PyUSB to use this resource type.
         No module named 'usb'
      VICP INSTR:
         Please install PyVICP to use this resource type.
      GPIB INSTR:
         Please install linux-gpib (Linux) or gpib-ctypes (Windows, Linux) to use this resource type. Note that installing gpib-ctypes will give you access to a broader range of functionalities.
         No module named 'gpib'
      GPIB INTFC:
         Please install linux-gpib (Linux) or gpib-ctypes (Windows, Linux) to use this resource type. Note that installing gpib-ctypes will give you access to a broader range of functionalities.
         No module named 'gpib'
@MatthieuDartiailh
Copy link
Member

MatthieuDartiailh commented Nov 28, 2023

Could you instrument a bit the code so that we get a better idea of what is going on ?
I think it may be helpful to:

  • print/log the list of discovery addresses over which we broadcast
  • check the pmap_list to see if broadcast fails on any address
  • increase the sleep duration

@MatthieuDartiailh
Copy link
Member

Reading my previous message I realize I was a vague. The function to instrument is the following: https://github.com/pyvisa/pyvisa-py/blob/main/pyvisa_py/tcpip.py#L394

@dstrande
Copy link
Author

It seems like the send succeeds but doesn't receive a response.

I pulled out this part of the code and ran it:

import socket
import ipaddress
from pyvisa_py.protocols import vxi11, rpc
import time
import psutil


broadcast_addr = []
for interface, snics in psutil.net_if_addrs().items():
    for snic in snics:
        if snic.family is socket.AF_INET:
            addr = snic.address
            mask = snic.netmask
            network = ipaddress.IPv4Network(addr + "/" + mask, strict=False)
            broadcast_addr.append(str(network.broadcast_address))


print("addresses: ", broadcast_addr)
pmap_list = [rpc.BroadcastUDPPortMapperClient(ip) for ip in broadcast_addr]
for pmap in list(pmap_list):
    pmap.set_timeout(0)
    pmap.send_port((vxi11.DEVICE_CORE_PROG, vxi11.DEVICE_CORE_VERS, rpc.IPPROTO_TCP, 0))

# Timeout for responses
print("pmap send: ", pmap_list)
time.sleep(5)

all_res = []
for pmap in pmap_list:
    resp = pmap.recv_port(
        (vxi11.DEVICE_CORE_PROG, vxi11.DEVICE_CORE_VERS, rpc.IPPROTO_TCP, 0)
    )
    print("response: ", resp)

    res = [r[1][0] for r in resp if r[0] > 0]
    res = sorted(res, key=lambda ip: tuple(int(part) for part in ip.split(".")))
    # TODO: Detect GPIB over TCPIP
    res = ["TCPIP::{}::INSTR".format(host) for host in res]
    all_res.extend(res)

Which returns:

addresses:  ['127.255.255.255', '10.0.0.255', '169.254.255.255']
pmap send:  [<pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x10c099650>, <pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x105d77510>, <pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x106a6c090>]
response:  []
response:  []
response:  []

@dstrande
Copy link
Author

Also here's the output on Windows:

addresses:  ['169.254.255.255', '10.0.0.255', '169.254.255.255', '127.255.255.255']
pmap send:  [<pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x000001A8746D7650>, <pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x000001A8748FC710>, <pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x000001A874695F50>, <pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x000001A8746A0BD0>]
response:  [(621, ('169.254.145.144', 111))]
response:  []
response:  [(621, ('169.254.145.144', 111))]
response:  []

@MatthieuDartiailh
Copy link
Member

Thanks ! Having the M2/Windows comparison is nice.

So we know that we are indeed sending requests and that we would be able to reach the instrument since we address the right subnet. So we need to understand why we do not get any response on Mac. I am not familiar with MacOS firewall settings but it may worth checking that it is not filtering either the query or responses.

@dstrande
Copy link
Author

I'm also not too familiar. Seems like my firewall is disabled though. If I ping the instrument I get a response as well:

PING 169.254.145.144 (169.254.145.144): 56 data bytes
64 bytes from 169.254.145.144: icmp_seq=0 ttl=64 time=0.567 ms
64 bytes from 169.254.145.144: icmp_seq=1 ttl=64 time=0.586 ms
64 bytes from 169.254.145.144: icmp_seq=2 ttl=64 time=0.589 ms
64 bytes from 169.254.145.144: icmp_seq=3 ttl=64 time=0.631 ms

Screenshot 2023-11-29 at 7 53 06 AM

@MatthieuDartiailh
Copy link
Member

Since I do not have a Mac on hand this is getting hard. Could you try to install wireshark and look at the traffic on the subnet 169.254 ?

@dstrande
Copy link
Author

Not fully sure what I'm looking at but the packets in blue occur regularly and the packet in yellow is from the script above.

Screenshot 2023-11-29 at 8 21 41 AM

@MatthieuDartiailh
Copy link
Member

Thanks. Could you do something similar on windows and confirm the IP address of the Mac on the 1698.254 subnet ?

If by chance you also have access to a linux setup, I would be curious to know what result you get on it.

@dstrande
Copy link
Author

Unfortunately I don't have access to linux. I can get a usb boot if you think it'll make a difference.

On Windows it's different, unsurprisingly I guess. The script starts with No. 43.

image

@dstrande
Copy link
Author

Also I've confirmed the 169.254 subnet on mac:

% ipconfig getifaddr en6
169.254.185.47

@dstrande
Copy link
Author

Maybe this isn't surprising, but I changed the test script above to include the devices address from the start ( line 8 broadcast_addr = ["169.254.145.145"]). And this is what is returned:

addresses:  ['169.254.145.145', '127.255.255.255', '10.0.0.255', '169.254.255.255']
pmap send:  [<pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x10124fe10>, <pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x100daf590>, <pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x1026c9650>, <pyvisa_py.protocols.rpc.BroadcastUDPPortMapperClient object at 0x100c960d0>]
b'\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02Y' ('169.254.145.145', 111)
response:  [(601, ('169.254.145.145', 111))]
response:  []
response:  []
response:  []

@CompThing
Copy link

CompThing commented Nov 30, 2023 via email

@MatthieuDartiailh
Copy link
Member

@CompThing may well be onto something. It is at the very least worth checking and documenting if it turns out it is the root cause.

@dstrande
Copy link
Author

dstrande commented Dec 1, 2023

Yes you're right. If I plug something into my network instead of directly into the Mac, it shows up for list_resources:

('ASRL/dev/cu.Bluetooth-Incoming-Port::INSTR', 'TCPIP::10.0.0.219::INSTR')

@MatthieuDartiailh
Copy link
Member

Could you try using a setting a static IP address for your Mac (in 192.168.) and see if it also works ?

If yes it means we simply need to document that relying on APIPA address is not supported.

@dstrande
Copy link
Author

dstrande commented Dec 1, 2023

No unfortunately. I did try that originally and it still doesn't work.

@CompThing
Copy link

CompThing commented Dec 1, 2023 via email

@dstrande
Copy link
Author

dstrande commented Dec 1, 2023

Yeah 169.254.100.101 / 255.255.0.0 and 169.254.145.45 / 255.255.0.0 on the instrument. No gateway needed correct?

Screenshot 2023-12-01 at 7 31 05 AM

@CompThing
Copy link

CompThing commented Dec 1, 2023 via email

@dstrande
Copy link
Author

dstrande commented Dec 1, 2023

Yeah that seems to work. Weird that Mac default to 255.255.0.0.

So for link-local Mac requires a 255.255.255.0 subnet, but no change for normal connections through a router.

@MatthieuDartiailh
Copy link
Member

I think it is not so much a question of mask than it is a question of the ip address prefix. As @CompThing pointed out the 169.255 prefix is special and this appears to be the root issue of your problem.

Could you make a PR adding this piece of information to the documentation ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants