Home AMX User Forum AMX Technical Discussion

Denon Connection refused error

Hi I am getting Connection Refused error when I use to connect my Denon receiver.
It works about 70% of the time but for some reason the it starts to give me Connection Refused error and I have to restart everything to clear up.
I was wondering is there a proper way to Open the Client and then Close it?

Here is what I have:

Localport = 0:11:0
IP_CLIENT_OPEN(dvIP_Denon.PORT,'192.168.1.136',23,1);

Feedback:
SendString to socket-local port (11) invalid
IPSocketManConnectTask - Connection Refused
CIpEvent::OnError 0:11:1

Comments

  • Is the Denon disconnecting or is ip_client_closed() being called in code? If the Denon is not disconnecting, best practices would be to leave the connection opened and never call ip_client_close().

  • JOHNBONZJOHNBONZ Posts: 99

    What I did was do a

    • OPEN
    • Command - like a Mute ON or Vol up or change sources
    • Close

    then when I wanted to do another Denon command I would repeat above.
    So what your suggesting do this:

    • OPEN
    • Command
    • set flag denonOpenForCommunication = 1 --- that states denon is ON

    then next time I execute a command

    • check flag to see if ON
      if denonOpenForCommunication
      then

    • Command
      -else if closed then

    • OPEN

    • Command

    ok I will remove all my IP_Client_Close - calls.
    just leave open for as long as Master Controller is running?

  • You'll still need an automatic reset / reconnect scheme if the unit does drop offline.

  • viningvining Posts: 4,368
    edited March 2019

    I would leave the connection open and poll for power and volume every 30 seconds or so. If the client drops offline automatically reconnect. Keep a var to track status of the connection.

    I use these 7 states but not on all clients::

    DEFINE_CONSTANT //CLIENT CONNECTIONS 
    
    #DEFINE IP_CLIENT_CONSTANTS
    
    CHAR IP_CLIENT_DISABLED     = 0;
    CHAR IP_CLIENT_DISCO        = 1;
    CHAR IP_CLIENT_PENDING      = 2;
    CHAR IP_CLIENT_CONNECTED    = 3;
    CHAR IP_CLIENT_DEVICE_READY = 4;
    CHAR IP_CLIENT_RX_DATA      = 5;
    CHAR IP_CLIENT_TX_DATA      = 6;
    
  • John NagyJohn Nagy Posts: 1,734

    No real need to keep tabs on the state... no harm in doing an OPEN before any command, and never closing or checking. If it's not open, it will. If it's open, your extra OPEN will fail but have no affect on anything. No housekeeping is required to "clean up" open connections. The other end will do that for you.

  • viningvining Posts: 4,368

    I’d rather track the state then see errors everytime we try to open a port that’s already open. It’s just a good habit to get into esepcially when you get into devices that require login, session keys and other PITA BS.

  • @vining said:
    I’d rather track the state then see errors everytime we try to open a port that’s already open. It’s just a good habit to get into esepcially when you get into devices that require login, session keys and other PITA BS.

    Quote here because I can't like it a second (or a third, or a ...) time

  • John NagyJohn Nagy Posts: 1,734
    edited March 2019

    I'm not really clear on how "seeing errors" is worse when you try to re-open an open port than seeing them when your poll fails because the port is closed. While I'd agree that the session key issue changes the balance of effort, with a normal device, your design takes a quantum level more code and much more cpu time to monitor and wait for an inevitable error that then triggers alternate action. If you don't poll immediately before a command, you don't know if your command will fail. If you do poll first, you delay your command, and must occasionally do the OPEN again before sending the waiting command.

    For many devices, you might send only dozens of commands a day or even per week. Polling endlessly and reopening for commands that may eventually be sent creates hundreds of thousands of unrequited handshakes and cpu/network traffic, as well as the opportunity to introduce code errors.

    Conversely, the "already open" error is a confirmation of continued connection you get to see at command events. It's good news, presented automatically by a proper operating system, with minimum code and cpu overhead.

    Or am I missing something? Asking for a friend.

  • viningvining Posts: 4,368

    Tracking the state is easy, just one variable setting in the online event handler, offline, onerror and I set pending before I call ip_open. Not really a lot of extra code or processing required.

    Polling lets me know the device is still communicating and if it stops I can send myself a notification or display a pop up suggesting to turn the devices hard button on like in the case of this Denon where a user, a cleaning person etc can press the power button. Sending a ?PWR query every 30 seconds isn't that big of a deal for the processor considering most processors aren't doing much most of the time if the majority of code is event driven.

    In a perfect world the polling shouldn't fail unless there's something wrong with hardware or the network so seeing an error is what you want and expect and if comms fail x amount of times you can send notifications, suspend the polling for x amount of time before trying again. Once your template is written it's easy to adapt to every devices particular needs. If for some reason the device falls offline I can open it and I never send polls when my Q.nHasItem so I don't slow the actual commands going to the device.

    I've never tried your method and the extra open call before each command shouldn't slow anything down but like I said I just hate looking at any errors and in my code I would have to add filters to prevent those errors from being logged, written to file and sent in that master's daily SITREP comms to my office's master where my master then send emails to myself whoever else is on the notifications list. So I guess in my case it's more code and more processing if I did it your way.

  • Just curious - anyone use the "native NetLinx boolean" method to track online status?

     data_event[dvIP]
     {
           online:
           {
               on[data.device, DEVICE_COMMUNICATING];
           }
           offline:
           {
               off[data.device, DEVICE_COMMUNICATING];
           }
     }
    
    timeline_event[IP_CONNECT]
    {
        if(![dvIP, DEVICE_COMMUNICATING])
        {
            ip_client_open(dvIP.PORT, .....);
        }
    }
    
  • I too use channel ON/OFF to track the connection state but I do so on a virtual device and not the physical device. I learned a long time ago that setting certain channels on a physical device, especially a network device, can sometimes result in unintended consequences. Always safer to use a virtual device.

    I also prefer tracking the connection state rather than blindly doing an IP_CLIENT_OPEN() without regarding to whether the connection has already been established. The open call can fail for more reasons than just the connection is already open so making an assumption that since the open fails that the connection must already be open is not necessarily a good one.

  • Exactly

    DEFINE_FUNCTION char[100] GetIpError (long iErrorCode) 
    {
        char iReturn[100];
    
        switch(iErrorCode) 
        {
        case  2 : iReturn = "'General failure (out of memory)'";
        case  4 : iReturn = "'Unknown host'";
        case  6 : iReturn = "'Connection refused'";
        case  7 : iReturn = "'Connection timed out'";
        case  8 : iReturn = "'Unknown connection error'";
        case  9 : iReturn = "'Already closed'";
        case 10 : iReturn = "'Binding error'";
        case 11 : iReturn = "'Listening error'";
        case 14 : iReturn = "'Local port already used'";
        case 15 : iReturn = "'UDP socket already listening'";
        case 16 : iReturn = "'Too many open sockets'";
        case 17 : iReturn = "'Local port not open'";
        default : iReturn = "'(',itoa(iErrorCode),') Undefined'";
        }
        return iReturn;
    }
    
    data_event[dvIP]
    {
      onerror:
      {
        amx_log(AMX_ERROR,"__FILE__,'->dvIP:onerror:',GetIpError(data.number)");
      }
    }
    
  • sentry07sentry07 Posts: 77

    @HARMAN_icraigie said:
    Just curious - anyone use the "native NetLinx boolean" method to track online status?

    In hindsight, that seems rational. I might have overdone my communication library. I've been developing it over the last 9 years. It does do a dandy IP connection, though.

  • @HARMAN_icraigie said:
    Just curious - anyone use the "native NetLinx boolean" method to track online status?

    I do, but like vining and others I add a 'connection pending' stage, so the controller will not try again to open a connection thats waiting for confirmation to open or for some reason be refused.

    BTW: I assume your code snippet about this is just that: a snippet you just typed. I would love for AMX to show a NetLinx template for serial/IP connections to, say, display devices, complete with all the householding: receiving an sending commands into and from the module, channel events, feedback channels, input- and output queueing, etc. Something that would be useable if you wanted to be as SNAPI compliant as possible, to exchange your own driver with the ones from AMX. I did that myself, but would be very curious to see how a feature complete example from our AMX overlords looked like... ;)

  • @richardherman said:

    I would love for AMX to show a NetLinx template for serial/IP connections to, say, display devices, complete with all the householding: receiving an sending commands into and from the module, channel events, feedback channels, input- and output queueing, etc. Something that would be useable if you wanted to be as SNAPI compliant as possible, to exchange your own driver with the ones from AMX.

    That exact thing is covered in the current Programmer 2 class. If its been awhile might be worth considering sitting in as a refresher...

    BTW - any programming class held out of the Richardson office is available to attend remotely

  • John NagyJohn Nagy Posts: 1,734
    edited March 2019

    @Reese Jacobs said:
    The open call can fail for more reasons than just the connection is already open so making an assumption that since the open fails that the connection must already be open is not necessarily a good one.

    The error returned I believe is "already open". I may misremember.... but it's something we've been doing for 20 years.

    You probably don't want to hear about how volume feedback is in many cases overkill too.
    (Short version, imagine that when you tell a device to be at 30%, you send "30%" to the panel display too. "But," you say, "What if the command fails, you wouldn't know!" Well, if volume fails, so will power and all the other commands, and you'll know pretty quick. "Oh!" you say, "what it someone manually moves the volume control! You'd never know!" Well, if it's too low or loud, if they touch VOL on a panel, it will immediately pick up again where you told it to be. See, you didn't want to hear this. Bring out the pitchforks and torches... and I concede in advance that there are remote operations where it can matter more.)

Sign In or Register to comment.