EPICS Home

Experimental Physics and Industrial Control System


 
1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025 
<== Date ==> <== Thread ==>

Subject: Re: Managing connections with asyn
From: Marco Filho via Tech-talk <tech-talk at aps.anl.gov>
To: Mark Rivers <rivers at cars.uchicago.edu>, "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov>
Cc: George Kontogiorgos <george.kontogiorgos at ess.eu>
Date: Fri, 9 Aug 2024 08:15:01 +0000

Hi, Mark! Thanks for the explanation.

I had some trouble initially understanding the distinct roles of asynManager, asynUser and asynCommon but with this things make more sense now. I was able to connect with:

asynUser* pasynDevice;
pasynCommonSyncIO->connect(name, 0, &pasynDevice, "");
pasynCommonSyncIO->connectDevice(pasynDevice);

Cheers :)

Marco


From: Mark Rivers <rivers at cars.uchicago.edu>
Sent: 08 August 2024 22:36:17
To: Marco Filho; tech-talk at aps.anl.gov
Cc: George Kontogiorgos
Subject: RE: Managing connections with asyn
 

Hi Marco,

 

My previous message had some typing errors.  It should read:

 

To connect to the device, i.e. open the socket, you need to call asynCommonSyncIO->connectDevice(), which calls asynCommon->connect().  I realize this is quite confusing, but it is explained in the documentation for asynCommonSyncIO which says:

 

Mark

 

 

From: Tech-talk <tech-talk-bounces at aps.anl.gov> On Behalf Of Mark Rivers via Tech-talk
Sent: Thursday, August 8, 2024 1:15 PM
To: Marco Filho <marco.filho at ess.eu>; tech-talk at aps.anl.gov
Cc: George Kontogiorgos <george.kontogiorgos at ess.eu>
Subject: RE: Managing connections with asyn

 

Hi Marco,

 

The documentation is here: https://epics-modules.github.io/asyn/asynDriver.html

 

asynManager is the low-level C code for asyn.    It is used to register asyn port drivers, connect asyn clients to the ports, and provide standard interfaces for asyn clients to communicate with asyn port drivers. 

 

asynUser is a C structure that is passed to asyn methods.  It is associated with a particular asyn port driver and address.

 

pasynManager->connectDevice().  This is the documentation for that function:


Connect the asynUser structure to a device specified by portName, addr. The port Name is the same as that specified in a call to registerPort. The call will fail if the asynUser is already connected to a device. If the port does not support multiple devices, than addr is ignored. connectDevice only connects the asynUser to the port driver for the portName,addr. The port driver may or may not be connected to the actual device. Thus, connectDevice and asynCommon:connect are completely different.

 

So this method just associates the asynUser structure with a particular asyn port and address.

 

pasynCommon->connect()

Connect to the hardware device or communication path. The queueRequest must specify priority asynQueuePriorityConnect.

 

This is a function that is implemented by the port driver.  When it is called it attempts to connect to the underlying device.  For an IP port it tries to open the socket.  If it succeeds it calls pasynManager->exceptionConnect() to signal to asynManager that the port is connected and ready to accept queueRequests.

 

You called pasynOctetSyncIO->connect().  That function results in a call to pasynManager->connectDevice(), NOT a call to pasynCommon->connect().  So it just disconnects the pasynUser from the asyn port driver, it does not close the socket.

 

To disconnect from the device, i.e. close the socket, you need to call asynCommonSyncIO->connectDevice(), which calls asynCommon->connect().  I realize this is quite confusing, but it is explained in the documentation for asynCommonSyncIO which says:

 

asynCommonSyncIO provides a convenient interface for software that needs to perform “synchronous” operations to an asyn device, i.e. that blocks while waiting for the port to be available and for the operation to complete. The code does not need to handle callbacks or understand the details of the asynManager and asynCommon interfaces.

 

Note that there is a potential for confusion in the connect* and disconnect* function names of this interface. For consistency with the other SyncIO interfaces, connect calls pasynManager->connectDevice, disconnect calls pasynManager->disconnect, connectDevice calls asynCommon->connect, and disconnectDevice calls asynCommon->disconnect.

 

I think your code should be changed to this:

 

    asynUser* pAsynUserOctet_, pasynUserCommon_;
    pasynOctetSyncIO->connect(name, 0, &pAsynUserOctet_, NULL);  // This connects the asynUser to the port for asynOctet communication
    pasynCommonSyncIO->connect(name, 0, &pAsynUserCommon_, NULL);  // This connects the asynUser to the port for connection control

    pasynCommonSyncIO->connectDevice(pasynUserCommon_);  // This opens the socket
    pasynCommonSyncIO->disconnectDevice(pasynUserCommon_);  // This closes the socket
    pasynCommonSyncIO->disconnect(name, 0, &pAsynUserCommon_, NULL);  // This disconnects the asynUser from the port, not strictly necessary

    pasynCommonSyncIO->disconnect(name, 0, &pAsynUserOctet_, NULL);  // This disconnects the asynUser from the port, not strictly necessary

 

Mark

 

 

From: Tech-talk <tech-talk-bounces at aps.anl.gov> On Behalf Of Marco Filho via Tech-talk
Sent: Thursday, August 8, 2024 9:55 AM
To: tech-talk at aps.anl.gov
Cc: George Kontogiorgos <george.kontogiorgos at ess.eu>
Subject: Managing connections with asyn

 

Hi!

I have kind of a simple question that has persisted for a long time about managing connections with asyn. For several reasons, I want my module to manage the connection and disconnection to the device.

For a minimalistic example, I created a python socket server with code copied from the internet that I append at the end of this e-mail. With an st.cmd file that has:

drvAsynIPPortConfigure("LOCALHOST", "127.0.0.1:65432", 0, 0, 0)

My python server prints:
Connected by ('127.0.0.1', 39696)

And returns the terminal once the client disconnects.
I then tried starting my asyn port with no autoconnect option:

drvAsynIPPortConfigure("LOCALHOST", "127.0.0.1:65432", 0, 1, 0)

And the python server doesn't print anything. In my module code, I passed the port name as an argument to the ADDriver constructor and tried to connect with it trough the code:

    printf("###########");
    asynUser* pAsynUser_;
    pasynOctetSyncIO->connect(name, 0, &pAsynUser_, NULL);
    pasynManager->disconnect(pAsynUser_);
    printf("###########");


But when I execute the IOC i get nothing in my python port. My ioc terminal prints:
(...)

drvAsynIPPortConfigure("LOCALHOST", "127.0.0.1:65432", 0, 1, 0)
MyDriverConfig("MYPORT", "LOCALHOST", 1000, 1000, 1, 0, 0)
###########
###########

(...)

I am still struggling with this because I clearly don't fully understand the differences between asynManager, asynUser, SyncIO, etc...
I looked at the examples in the asyn module and in ADmythen module, but they all use asyn AutoConnect (or maybe I missed something). They are good for showing how to write and read trough the code, but I wasn't able to understand how to disconnect and conenct to the port's IP.

Can someone explain what am I doing wrong?

Thanks in advance :)

--------------------------------------

Python server:

# echo-server.py

import socket

HOST = "127.0.0.1"  # Standard loopback interface address (localhost)
PORT = 65432  # Port to listen on (non-privileged ports are > 1023)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    conn, addr = s.accept()
    with conn:
        print(f"Connected by {addr}")
        while True:
            data = "">             if not data:
                break
            conn.sendall(data)

 


References:
Managing connections with asyn Marco Filho via Tech-talk
RE: Managing connections with asyn Mark Rivers via Tech-talk
RE: Managing connections with asyn Mark Rivers via Tech-talk

Navigate by Date:
Prev: RE: Install issues for labCA (channel access interface for matlab) Freddie Akeroyd - STFC UKRI via Tech-talk
Next: Long string PV access in CA client. Li, Ji via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025 
Navigate by Thread:
Prev: RE: Managing connections with asyn Mark Rivers via Tech-talk
Next: Long string PV access in CA client. Li, Ji via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025