Blocking TCP requests (LUA)

Discussions of Q-SYS hardware and software.

Moderators: Cameron Shoffner, Christian Cook, Kirk Fyvie, Martin Barbour, Fred Thomke, Gary Evans_QSC, Chris Brouelette

Sun Feb 12, 2017 8:09 pm

  • Just wondering if there is a way to execute a blocking TCP request - currently they are executed in a non-blocking fashion with an event handler; my issue is that I have a device (or rather a series of devices) which I find through a multicast UDP "Ping" basically - each box then responds with its IP address, name and ID number. Then I need to connect to each one to pull their configuration (whether it is a transmitter or reciever is basically all I care about). Theoretically I want to do this every time the UCI changes to a certain page as I cannot guarantee states have not changed since power on.

    So programatically I cannot just create "X" sockets - we are talking potentially 40 devices in addition to whatever else qSys is controlling so I don't think I would want to create that many sockets even if I could - because I don't know what "X" is - potentially that would also mean I would need to write "X" event handlers (can I pass additional parameters to the function assigned to the EventHandler outside of what it expects?). What I would really like to do is create a socket, connect to 1, send it a request for its parameters, recieve them, close the socket and then move on to number 2 utilising the same socket.

    I know that as far as speed to execute this will be very slow - especially as each box may take up to a second to send its data depending on what it is doing at the time but I want to avoid stressing the core too much - as it has many other things to wory about.

    I suppose theoretically I could make a "manual" loop by having a variable "i" for the current device number and a variable "iMax" with the total number of devices declared at a global level, then have function "f" configure and connect the socket and send the request and then the sockets handler close the socket after valid data is recieved, increment 'i', ensure "i" is <= "iMax" and then call f(i) but I wonder if I then end up with the risk of chewing through memory - ie will everything in memory from f(1) still be in memory when f(iMax) is being run or will it be cleaned up after each itteration.

    Some ideas would be great - at the moment I am contemplating outsourcing it to some python running on a raspberry pi or something and basically making the pi a router so that the qSys can just have a permanant connection to the Pi and the Pi will handle all the socket connections.

    Posts: 12
    Joined: Thu May 05, 2016 8:46 pm

Tue Feb 14, 2017 1:02 am

  • There's no synchronous sockets API, I'm afraid - but personally I think that's a good thing.

    There shouldn't be any issue running 40 socket connections from Q-Sys. It's Linux under the hood, and Linux servers frequently serve thousands or even tens of thousands of simultaneous socket connections.

    Alternatively, if you do use an EventHandler to increment i, disconnect and reconnect the socket, then send the next query, you have no recursion, so there's no memory issue there.

    RasPi is unnecessary.


    Possibly an old pro
    Posts: 26
    Joined: Fri Nov 06, 2015 1:59 am

Tue Feb 14, 2017 4:16 pm

  • Cheers Michael for your response. Good to know that it should not bog the core down too much.

    As an aside - Are you able to assist with how I would deal with the following scenario: I send a 16 byte packet to a multicast address that a number of devices are listening on - easy enough as in this case it is 16 bytes of null. Each device returns a response to me which is documented as follows:

    Code: Select all
    typedef struct _reply_struct_
    AST_Device_Type device_type;
    AST_Device_Function device_function;
    char device_status[MAX_STATUS_LENGTH];
    char device_name[MAX_NAME_LENGTH];
    char device_macid[MAX_MACID_LENGTH];
    char device_ip[MAX_IP_LENGTH];

    I can send my packet no dramas and my event handler has a print("recieved") is telling me I am getting the data back, but I cannot print(packet.Data) it (I get a blank line) which makes me wonder if I can treat this data like a string or is qSys treating it as something else. When I use a packet sending application to monitor the reply I get something like this:


    The first item that is underlined, that is the expected device type
    The second item I am assuming is device function (I don't have a list of the expected values for that parameter)
    s_srv_on is a status condition
    rack2-dec-0002 is in the correct format for a name (hostname-[dec|enc]-[unitID])
    The next underlined item would be the mac address
    and then the IP. I am just wondering why dumping this packet is not giving me anything in the debug console.

    If I can treat it like a string I could probably figure out string.Match parameters for each item but I would really like to actually see the data that came in just to make sure it is getting in properly.

    Even if I can only see the human-readable ASCII characters that would help.
    Posts: 12
    Joined: Thu May 05, 2016 8:46 pm

Wed Feb 15, 2017 12:34 am

  • Never mind... when I got to the office I tested pulling the sub strings using string.match and string.byte with success.So not so concerned about seeing the whole packet.
    Posts: 12
    Joined: Thu May 05, 2016 8:46 pm

Return to Q-SYS Support

  • Users browsing this forum: No registered users and 3 guests