Home AMX User Forum AMX Technical Discussion

How to detect source IP in DATA_EVENT at server side

Hi all,
i need to control a Sony SRG-300H camera. The problem is that this is an IP Camera through UDP, so i had to open a client port to send messages to the camera and open a server port to receive the responses from the camera, as follows:
ip_client_open(dvCameraSend.PORT,acIPCam,52381,IP_UDP)     //To send messages to the camera

.
.
.

DATA_EVENT[0:1:0]
{
    online:
    {
        ip_server_open(dvCameraRcv.PORT,52381,IP_UDP)    //To receive messages from the camera
    }
}

Everything works fine if i control ONE camera, but if i try to connect to more cameras (two, for example). I can send the messages correctly because with "ip_client" i have to especify the ip of the camera, but at the receive side (server side), because ALL messages from ALL cameras are received at the same port (52381 UDP), i have no way to detect which message is from which camera.

So the question is: Is there a way to detect the source ip of a message received inside a DATA_EVENT of a server port?
Need to implement something like this:
DATA_EVENT[dvCameraRcv]
{
    string:
    {
        if(data.source.ip == 192.168.1.100)
            //do something
        else if(data.source.ip == 192.168.1.101)
            //whatever
        .
        .
        .
    }
}

Comments

  • ericmedleyericmedley Posts: 4,177
    Create one AMX IP port for each individual camera.
  • MorgoZMorgoZ Posts: 116
    Yes, i´ve created one ip port for each client connection and they work well.
    But, if i create one ip port for each server connection, just works the first one created, because Netlinx works as follows, for example:
    "link port 20 to UDP port 52381 AND link port 30 to UDP port 52381" -ALL Cameras replies ALLWAYS to por 52381, no way to change it-. So, with that configuration the only port that receives messages in practice is the por 20, at port 30 i receive nothing.
    And that is why i think that a solution would be to detect the source IP of the message at port 20.

    Thanks.
  • viningvining Posts: 4,368
    To get the client's IP that connected to a Netlinx server you use DATA.SOURCEIP in the online handler like so:
    DATA_EVENT[dvServer]
         
         {
         ONLINE:
    	  {
    	  cSSourceIP = DATA.SOURCEIP;
    	  nServerConAttempt = 0;
    	  if(nStats[SSERV_STAT_DEBUG])
    	       {
    	       SEND_STRING 0,"13";
    	       SEND_STRING 0,"'(***********************************************************)'";
    	       SEND_STRING 0,"'       Sitrep Server Mod ',itoa(nStats[SSERV_STAT_INSTANCE]),', Has Client Connected           '";	
    	       SEND_STRING 0,"'(***********************************************************)'";
    	       SEND_STRING 0,"13";
    	       }
    	  fnServer_DeBug("'CLIENT ONLINE'");
    	  if(nRequireLogin == LOGIN_REQUIRED)
    	       {
    	       nLogIn_Step = LOGIN_INIT;
    	       SEND_STRING dvServer, "'|*************************|',STR_CRLF";
    	       SEND_STRING dvServer, "'|*** AMX SITREP SERVER ***| !---> (type exit or quit to close connection) <---!',STR_CRLF";
    	       SEND_STRING dvServer, "'|*************************|',STR_CRLF";
    	       SEND_STRING dvServer, "'*',STR_CRLF,'*',STR_CRLF";
    	       SEND_STRING dvServer, "'Login Required !',STR_CRLF"; 
    	       SEND_STRING dvServer, "'*',STR_CRLF";
    	       SEND_STRING dvServer, "'user: '"; 
    	       }
    	  else
    	       {
    	       nLogIn_Step = LOGGED_IN;
    	       }
    	  if(nStats[SSERV_STAT_TYPE])// == SSSERV_TYPE_SITREP)
    	       {
    	       WAIT 300 'IDLE_TIMEOUT'
    		    {
    		    fnServer_DeBug("'RX_Msg, Closing Server :DEBUG<',ITOA(__LINE__),'>'");
    		    fnCloseServer(); 
    		    }
    	       }
    	  }
    

    I don't get why you would need to open a server port to rx from the camera though, it makes no sense. You should just need a Netlinx port/socket per camera like:
    dvAxisCam_1             = 0:15:0;
    dvAxisCam_2             = 0:16:0;
    dvAxisCam_3             = 0:17:0;
    dvAxisCam_4             = 0:18:0;
    
    Open a connection to each camera's IP and the camera should respond to the client's (Netlinx) socket. Netlinx should be able to handle 200 sockets to 200 servers (cameras) on the same server port and obviously different IPs.
  • MorgoZMorgoZ Posts: 116
    Thank you vining,

    the approach that you suggest opening a socket connection for each camera is correct IF the cameras would be TCP cameras, but it doesn´t work with a UDP connection, because UDP is not a connection oriented protocol.

    I´ll try to explain how do the cameras manage the communication with a controller.

    NETLINX PORT (Logic port) || MASTER SOCKET PORT (Real port) || CAMERA PORT

    20
    > 2025 (anyone selected by the Master)
    > 52381 (listening port)

    30 (listening) <
    52381 (programatically configured) <
    3456 (anyone selected by the camera to answer the Master)


    Because it is UDP, the camera hasn´t got to answer the sender through the same port it receives the message (in the example, 2025), and the connection protocol is defined by the manufacturer. In this case, the controller (Master) has to connect to the camera to the 52381 UDP port, and by Sony definition, the camera allways answers the sender to the 52381 port. The problem is that i can´t manage the Master socket ports (i can´t tell the Master to open "real" port 52381 to connect the camera), the "real" ports are manages by the Master and this process is hidden (transparent) to the programmer, so i have to open a server connection appart.

    Anyway, thanks for the "SOURCEIP" property. I think this will help ;)
  • viningvining Posts: 4,368
    Hmmm, never really played with UDP devices but it seems weird. Have you played with IP_UDP_2WAY to see what that does.
    Receiving Data with UDP
    Since UDP is connection-less, no formal agreement has been made between the client and server to exchange data. The client simply sends a UDP message and hopes the server is listening. In many protocols that use UDP for communication, there is an implied agreement for the client to receive date from the server.
    
    When a UDP client socket in created, the socket is assigned a UDP/IP port number, not to be confused with local port. This UDP/IP port will be used to send UDP messages. The server, if listening, will receive this message along with the IP address and UDP/IP of the client who sent the message.
    
    Some UDP protocols have an implied agreement that the server will be able to respond to the client by sending a response back to the IP address and UDP/IP from where the message originated. Although the UDP protocol does not specify that the client must expect to receive messages in this way, many UDP/IP require the client to listening for response after sending a message.
    
    NetLinx has two UDP client implementations. These are UDP (2) and UDP With Receive (3). The first implementation only sends message and cannot receive messages. UDP with Receive will send and receive messages on a single UDP/IP port.
    
    It may seem like UDP (2) is not needed; however, it still serves and important purpose. Imagine you wanted to send a UDP message and expect a response. The proper way to open this type of socket, assuming you want to send a UDP message to 192.168.0.1 on UDP/IP port 6000, is:
    
    IP_CLIENT_OPEN(dvUDPClient,'192.168.0.1',6000, IP_UDP_2WAY)
    
    Now, if you were also writing the code for 192.168.0.1, you would need to have opened a UDP server using the following:
    
    IP_SERVER_OPEN(dvUDPServer,6000,IP_UDP)
    
    When the message is received at 192.168.0.1, the message will be delivered to the DATA_EVENT for dvUDPServer and the IP address UDP/IP port of the sender of the message will be available in the DATA.SOURCEIP and DATA.SOURCEPORT variables. A UDP (2) socket would be used in this case to send a response to the client. Since we will no longer need to listen after sending the response, since there would be no response to the response, we would open the socket using the following:
    
    IP_CLIENT_OPEN(dvUDPClient,DATA.SOURCEIP,DATA.SOURCEPORT,IP_UDP)
    
    Note that UDP with Receive (3) is only available when calling IP_CLIENT_OPEN.
    
    
  • dchristodchristo Posts: 177
    Since the camera is replying to the same port you're sending, you should be able to use IP_UDP_2WAY to send/recieve on the same IP socket. Then you can open multiple ports, one for each camera, since they'll all have different IP addresses.

    --D
  • Hi Guys, is module SRG120HD compatible with SRG300H ??
Sign In or Register to comment.