Home AMX User Forum NetLinx Studio

TCP/IP control of Denon 3808ci

I'm having a little trouble getting the Denon 3808ci to respond to send_string commands. I'm able to connect via TCP/IP (port 23), and get the string responses from the receiver (via data.text). The receiver won't, however, respond to any thing that I send via send_string.

The funny thing is, if I connect via telnet or hyperterminal, I'm able to issue a command, and the receiver responds.

In hyperterminal / telnet I'll type something like:
SIDVD
followed by hitting the Enter key. The input changes to DVD.

The Denon protocol indicates the following:
Command Structure: COMMAND + PARAMETER + CR (0x0D)
Example Command: SIDVD<CR>

However, sending a string (from within the code, or via telnet connected to the master controller) results in no response from the 3808ci. Examples of send_string commands I have sent are:
send_string dvAVR3808ci_1_IP,"'SICD',13"
send_string dvAVR3808ci_1_IP,"'SIDVD',$0D"
send_string dvAVR3808ci_1_IP,"'SIDVD',13"
As well as many many other combinations.

'm a bit stuck, as I know the TCP/IP communications are working in that I am able to parse string information from the 3808ci via data.text. I'm assuming that I'm missing something, or am doing something wrong when it comes to the carriage return character, or something similar.

To sum it up:
- Can connect to the 3803ci via telnet / hyperterminal (port 23) to both receive string status information, and issue commands that the 3808ci responds to.
- When running the TCP/IP code on the NetLinx controller, I'm able to successfully open TCP/IP communications, and receive string information from the 3808ci (which I'm outputting via send_string 0,...). However when issuing commands to the 3808ci, there is no response.

Thanks in advance for any help.

The code used for opening TCP/IP communications (I followed the example code listed on AMX.com). Please note that these are only bits of the code that are related to TCP/IP communications (the full code compiles and runs fine):
DEFINE_DEVICE

dvAVR3808ci_1_IP = 0:3:0

DEFINE_CONSTANT

TRUE = 1
FALSE = 0
TCP = 1
UDP = 2
RETRY_TIME = 300	//30 seconds

DEFINE_VARIABLE

CONSTANT char cServerAddress[13] = '192.168.1.220';

// Using server port 23 (Telnet) in this example.
CONSTANT LONG lServerPort = 23;
INTEGER bClientOnline; 	// Flag: TRUE when client is connected
INTEGER bClientKeepOpen; 	// Flag: keep the client open at all times

DEFINE_START

// Attempt to open a TCP connection to the server.
IP_CLIENT_OPEN (dvAVR3808ci_1_IP.port,cServerAddress,lServerPort,TCP);

DEFINE_EVENT

DATA_EVENT [dvAVR3808ci_1_IP]
{
    // Online handler runs when a successful connection is made.
    ONLINE:
    {

        // We have communication. Can send strings to IP device now.
        bClientOnline = TRUE;
    }

    // Offline handler runs when connection is dropped/closed.
    OFFLINE:
    {
        // NOTE: Certain protocols (such as HTTP) drop the connection
        // after sending a response to a request. For those protocols,
        // this is a better place to parse the buffer than in the STRING
        // handler. There will be a complete reply in the buffer.

        bClientOnline = FALSE;
        // Attempt to reestablish communications, if desired.
        IF (bClientKeepOpen)
            WAIT RETRY_TIME
                IP_CLIENT_OPEN (dvAVR3808ci_1_IP.port,cServerAddress,lServerPort,TCP);
    }

    // Data event runs when we get messages from the server.
    STRING:
    {
	send_string 0,"' *** 3808ci Telnet string: ',data.text,$0D"
        // Buffer parsing goes here.
        // May need to ACK initial message from server to establish connection.

        // NOTE: Even if parsing responses in OFFLINE, you should still have
        // an empty STRING handler to prevent mainline from running needlessly
        // every time a string comes in.
    }

    // Onerror runs when attempt to connect fails.
    ONERROR:
    {

        SWITCH (DATA.NUMBER)
        {

            // No need to reopen socket in response to following two errors.
            CASE 9: 	// Socket closed in response to IP_CLIENT_CLOSE.
            CASE 17: 	// String was sent to a closed socket.
            {
            }
            DEFAULT: 	// All other errors. May want to retry connection.
            {
                IF (bClientKeepOpen)
                    WAIT RETRY_TIME
                        IP_CLIENT_OPEN (dvAVR3808ci_1_IP.port,cServerAddress,lServerPort,TCP);
            }
        }
    }
}

Comments

  • DHawthorneDHawthorne Posts: 4,584
    My limited experience with Denon IP control is that they do not like you to leave the connection open. There is little to no delay re-opening it, so what I did was put a timeout: if there was no activity (incoming or outgoing) on the connection, I drop it; when I need to send a command, I open it up again. I believe I settled on a five minute timeout. If I left it open all the time, however, the Denon did just what you describe, and wouldn't respond at all until I reset it. It re-conects so quickly, there is no noticeable delay when it times out and I need to send a command.
  • I've actually tried closing the TCP communications, re-opening communications, and then sending the string... with no success. Like I said, I can issue a command directly from telnet or hyperterminal, and the receiver responds immediately. However issuing through NetLinx using send_string... I get nothing. I must be overlooking something here.
  • a_riot42a_riot42 Posts: 1,624
    kingpikey wrote: »
    I've actually tried closing the TCP communications, re-opening communications, and then sending the string... with no success. Like I said, I can issue a command directly from telnet or hyperterminal, and the receiver responds immediately. However issuing through NetLinx using send_string... I get nothing. I must be overlooking something here.

    I don't see any culprits in the code you posted, but you didn't include the send_string code. The commands are correct, I have used that same protocol many times. "'SIDVD',$0D" should work. Have you tried putting your ip_client_open call in a button event and triggering it rather than calling it in define_start? Can't think of much else that could go wrong other than everything.

    You might want to flush out your debug code as well. Stick this in your onerror event and see if anything gets printed.
    onerror:
    {
      print("'Telnet Event: Error:(',itoa(data.number),')'")
    	
      switch (data.number)
      {
        case 2:
        {
          print("'General failure (out of memory)'")
        }
        case 4:
        {
          print("'Unknown host'")
        }
        case 6:
        {	
         print("'Connection refused'")
        }
        case 7:
        {
          print("'Connection timed out'")
        }
        case 8:
        {
          print("'Unknown connection error'")
        }
        case 14:
        {
          print("'Local port already used'")
        }
        case 16:
        {
          print("'Too many open sockets'")
        }
        case 17:
        {
          print("'Local Port Not Open'")
        }
      }
    }
    

    Paul
Sign In or Register to comment.