Home AMX General Discussion

HTTP commands of Dahua NVR

Hi guys,

I wanted to ask on here as im not sure whether this will be ok.
We are hoping to implement control of a Dahua NVR which has firmware on it to allow HTTP control of its onscreen display.
The document reckons the command for nav up would be;

http://admin:[email protected]:80/cgi-bin/keyBoardCtrl.cgi?setAction=Up

I have done other devices using HTTP Get type commands by connected to the device on say Port 80 TCP , on the button press,
then linking the command as per below on a button switch case;

CASE 1: SEND_STRING dvDevice_IP,"'GET //cgi-bin/keyBoardCtrl.cgi?setAction=Up HTTP/1.1',$0D,$0A,$0D,$0A"

Then disconnect the connection on release..

I have never had to supply credential before.

How do I go about providing credentials in the connect? at the moment my connects are basic;

DEFINE_CALL 'XBMC CONNECT'
{
IP_CLIENT_OPEN(dvXBMC_IP.port,XBMC_IP_IpAddress,XBMC_IP_Port,IP_TCP)
}

DEFINE_CALL 'XBMC DISCONNECT'
{
IP_CLIENT_CLOSE(dvXBMC_IP.port)
}

Any direction really appreciated..

Comments

  • sling100sling100 Junior Member Posts: 104
    You need to encode the user and password string rather than sending it in plain text. There is a good function for base 64 encoding on the forums if you have a look.

    The resulting string then needs to be sent as an Authorization header

    SEND_STRING dvDVR,"'GET /cgi-bin/keyBoardCtrl.cgi?setAction=Up HTTP/1.1',13,10"
    SEND_STRING dvDVR,"'Authorization: Basic ',fnBase64('admin:admin'),13,10,13,10"

    Hopefully that should work.

    Simon
  • ericmedleyericmedley Senior Member - 4000+ posts Posts: 4,177
    Keep in mind that the communication has to be managed by you. For example, when you send a rs232 string - all you do is "send string blah blah blah. the processor is handling all the protocols to actually do it under the hood. With IP communications you are required to do an additional step.
    The two steps are 1) establish the connection socket and 2) once the connection is established - send your message.

    So, you need to have a DATA_EVENT[dvXBMC_IP] on the IP port. In that data_event>online: is where you now know the IP Port is connected and it is now time to send your message.
  • mkleynhansmkleynhans Junior Member Posts: 78
    Guys, thanks and also thanks to Chip Moody for his Base64 code. I had perfect control of the Dahua NVR onscreen display in the office using a NI3101SIG.
    I then took this code and the NVR to site and installed it onto the customers NI3100 and it wouldnt work......
    I can get the onscreen display to change by typing the commands into a browser and then manually inputting username and password into the prompt but I just cannot get it to work from Netlinx.
    Lots of head scratching and back onto it tomorrow I guess... I am wondering if 3.60 Duet firmware may be the issue as our 3101Sig is on 4.xx.. very strange..
  • John NagyJohn Nagy CineTouch Product Manager Posts: 1,563
    Telnet into the NI and PING the IP of the screen to see if you have comms at all. You may be on different subnets. Firmware is UNLIKELY the cause of this one.
  • mkleynhansmkleynhans Junior Member Posts: 78
    Thanks for the tip John, I have pinged 192.168.1.238 (The NVR) from 192.168.1.200 (NI-3100 Master) and it looks OK.. (Aparently 192.168.1.238 is alive)
    I have checked the router and no VLANs are setup, very odd indeed.. The only difference between the controllers is our office unit a NI-3101-SIG on 192.168.0 range with Duet firmware of 4.1.373 and the customers is a NI-3100 on a 192.168.1 range with firmware of 3.60.453.

    			PROGRAM_NAME='DAHUA_NVR'
    
    			DEFINE_DEVICE
    
    			dvNVR_IP        =     0:10:1
    
    			dvTP_CCTV_1_1         =    10001:21:1
    			dvTP_CCTV_1_2         =    10002:21:1
    			dvTP_CCTV_1_3         =    10003:21:1
    			dvTP_CCTV_1_4         =    10004:21:1
    			dvTP_CCTV_1_5         =    10005:21:1
    			dvTP_CCTV_1_6         =    10006:21:1
    			dvTP_CCTV_1_7         =    10007:21:1
    			dvTP_CCTV_1_8         =    10008:21:1
    			dvTP_CCTV_1_9         =    10009:21:1
    			dvTP_CCTV_1_10        =    10010:21:1
    
    			DEFINE_CONSTANT
    
    			NVR_IP_IpAddress     =     '192.168.1.238'
    			NVR_IP_Port         =     80
    
    			DEFINE_VARIABLE
    
    			DEV dvTP_NVR[]=
    			{
    			dvTP_CCTV_1_1, dvTP_CCTV_1_2, dvTP_CCTV_1_3, dvTP_CCTV_1_4,
    			dvTP_CCTV_1_5, dvTP_CCTV_1_6, dvTP_CCTV_1_7, dvTP_CCTV_1_8,
    			dvTP_CCTV_1_9, dvTP_CCTV_1_10
    			}
    
    			iNVR_IP_Connected     =     0
    
    			DEFINE_EVENT
    
    			DATA_EVENT[dvNVR_IP]
    			{
    			    ONLINE:
    			    {
    			       iNVR_IP_Connected = 1
    			    }
    			    OFFLINE:
    			    {
    			      iNVR_IP_Connected = 0
    			    }
    			}
    
    
    			BUTTON_EVENT[dvTP_NVR,BUTTON.INPUT.CHANNEL]
    			{
    			PUSH:
    			   {
    			   fnNVRIPConnect()
    			   SWITCH(BUTTON.INPUT.CHANNEL)
    			   {
    			   CASE 1:    { //Up
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/keyBoardCtrl.cgi?setAction=Up HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 2:    { //Down
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/keyBoardCtrl.cgi?setAction=Down HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 3:    { //Left
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/keyBoardCtrl.cgi?setAction=Left HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 4:    { //Right
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/keyBoardCtrl.cgi?setAction=Right HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 5:    { //Enter
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/keyBoardCtrl.cgi?setAction=Enter HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 6:    { //Escape
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/keyBoardCtrl.cgi?setAction=Escape HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 11:    { //Camera 1
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=0 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 12:    { //Camera 2
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=1 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 13:    { //Camera 3
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=2 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 14:    { //Camera 4
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=3 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 15:    { //Camera 5
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=4 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 16:    { //Camera 6
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=5 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 17:    { //Camera 7
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=6 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 18:    { //Camera 8
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=7 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 19:    { //Camera 9
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=8 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 20:    { //Camera 10
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=9 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 21:    { //Camera 11
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=10 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 22:    { //Camera 12
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=11 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 23:    { //Camera 13
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=12 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 24:    { //Camera 14
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=13 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 25:    { //Camera 15
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=14 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 26:    { //Camera 16
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split1&group=15 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 31:    { //Split4
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split4&group=0 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 32:    { //Split9
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split9&group=0 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   CASE 33:    { //Split16
    			           SEND_STRING dvNVR_IP,"'GET /cgi-bin/split.cgi?action=setMode&channel=0&mode=Split16&group=0 HTTP/1.1',13,10"
    			           SEND_STRING dvNVR_IP,"'Authorization: Basic ',fnBase64('remote:remote2017'),13,10,13,10"
    			           }
    			   }
    			   }
    			   RELEASE:
    			   {
    			   fnNVRIPDisconnect()
    			   }
    			}
    
    			DEFINE_FUNCTION fnNVRIPConnect()
    			{
    			IP_CLIENT_OPEN(dvNVR_IP.port,NVR_IP_IpAddress,NVR_IP_Port,IP_TCP)
    			}
    
    
    			DEFINE_FUNCTION fnNVRIPDisconnect()
    			{
    			IP_CLIENT_CLOSE(dvNVR_IP.port)
    			}
    
    			DEFINE_FUNCTION CHAR[255] fnBase64 (CHAR Source[])
    			{
    			 LOCAL_VAR CHAR    Uncode[255]      // Password protected sites require that the
    			 LOCAL_VAR CHAR    Coded[255]       // username & password get encoded together in
    			 LOCAL_VAR CHAR    Munch[3]         // Base64 format.  Don't know what Base64 is?
    			 LOCAL_VAR CHAR    Chew[4]          // Neither did I until I looked at
    			 LOCAL_VAR INTEGER Step             // http://freesoft.org/CIE/RFC/2065/56.htm
    			                                    // and http://freesoft.org/CIE/RFC/1521/7.htm
    			 Coded = ''
    			 Chew = '    '
    			 Uncode = Source
    			 WHILE (LENGTH_STRING(Uncode) >= 3)
    			 {
    			   Munch = GET_BUFFER_STRING(Uncode,3)
    			   Chew[1] = Munch[1]
    			   Chew[1] = Chew[1] / 4    
    			   Chew[2] = ((Munch[1] * 16) BAND $30)
    			   Chew[2] = Chew[2] + ((Munch[2] / 16) BAND $F)    
    			   Chew[3] = ((Munch[2]*4) BAND $3C)
    			   Chew[3] = Chew[3] + ((Munch[3] / 64) BAND $3)    
    			   Chew[4] = Munch[3] BAND $3F
    			   Coded = "Coded,Chew"
    			 }
    			 SELECT
    			 {
    			   ACTIVE (LENGTH_STRING(Uncode) = 2):
    			   {
    			     Munch = "GET_BUFFER_STRING(Uncode,2)"
    			     Chew[1] = Munch[1]
    			     Chew[1] = Chew[1] / 4      
    			     Chew[2] = ((Munch[1] * 16) BAND $30)
    			     Chew[2] = Chew[2] + ((Munch[2] / 16) BAND $F)        
    			     Chew[3] = ((Munch[2]*4) BAND $3C)      
    			     Chew[4] = 64
    			     Coded = "Coded,Chew"        
    			   }
    			   ACTIVE (LENGTH_STRING(Uncode) = 1):
    			   {
    			     Munch = GET_BUFFER_STRING(Uncode,1)
    			     Chew[1] = Munch[1]
    			     Chew[1] = Chew[1] / 4      
    			     Chew[2] = ((Munch[1] * 16) BAND $30)      
    			     Chew[3] = 64
    			     Chew[4] = 64
    			     Coded = "Coded,Chew"  
    			   }
    			 }
    			 FOR (Step = 1;Step <= LENGTH_STRING(Coded);Step++)
    			 {
    			   SELECT
    			   {
    			     ACTIVE (Coded[Step] <= 25): Coded[Step] = Coded[Step] + 65
    			     ACTIVE (Coded[Step] <= 51): Coded[Step] = Coded[Step] + 71
    			     ACTIVE (Coded[Step] <= 61): Coded[Step] = Coded[Step] - 4
    			     ACTIVE (Coded[Step] = 62):  Coded[Step] = '+'
    			     ACTIVE (Coded[Step] = 63):  Coded[Step] = '/'
    			     ACTIVE (coded[Step] = 64):  Coded[Step] = '='
    			   }
    			 }
    			 RETURN Coded
    			}
    
    



  • viningvining X Member Posts: 4,368
    John Nagy wrote: »
    Telnet into the NI and PING the IP of the screen to see if you have comms at all. You may be on different subnets. Firmware is UNLIKELY the cause of this one.

    Firmware on the NVR might be a possibility but I agree not he master. I've come across several devices over the years that would not work because of the firmware variant used. Heck even when AMX came out with that audio system whose name escapes me they changed the communication baud rate between versions with out documenting that fact so the NVR could have changed many things from port or going from HTTP/1.0 to 1.1 or vice verse between versions.
  • mkleynhansmkleynhans Junior Member Posts: 78
    I just visited site and amended the code to get some feedback.. I'm getting this back...

    Line 5 (14:17:29):: HTTP/1.1 401 Unauthorized$0D$0AWWW-Authenticate: Digest realm="Login to 1L04659PAMZVS6J",qop="auth",nonce="1659866321",opaque="9ceb3a49

    Does this mean digest type authentication? I defintately had it working perfectly in our office - this is driving me nuts =/
  • mkleynhansmkleynhans Junior Member Posts: 78
    Just incase anyone else wants to control Dahua NVR's (To save them hassle), the NVR's that I have received ship with Basic Authentication and after being connected to the internet for 10 minutes, auto update their web servers to insist on Digest Authentication. They haven't confirmed this but I have seen it happen on three units now. If I send basic auth commands to it out of the box, it works for 10 minutes and voila... error messages.
    Have parsed digest info and sent back the correct credential and am controlling perfectly again...
    DEFINE_FUNCTION fnParseNVRBuffer()
    {
    WHILE (FIND_STRING (CnvrBuffer, 'WWW-Authenticate: Digest realm="', 1))
        {
        REMOVE_STRING (CnvrBuffer, 'WWW-Authenticate: Digest realm="', 1)
        cRealm=LEFT_STRING(CnvrBuffer, FIND_STRING(CnvrBuffer, '",', 1) -1)
        cRealmActual = "'"',cRealm,'"'"
        REMOVE_STRING (CnvrBuffer, 'qop="', 1)
        cQop=LEFT_STRING(CnvrBuffer, FIND_STRING(CnvrBuffer, '",', 1) -1)
        REMOVE_STRING (CnvrBuffer, 'nonce="', 1)
        cNonce = LEFT_STRING(CnvrBuffer, FIND_STRING(CnvrBuffer, '",', 1) -1)
        REMOVE_STRING (CnvrBuffer, 'opaque="', 1)
        cOpaque = LEFT_STRING(CnvrBuffer, FIND_STRING(CnvrBuffer, '"', 1) -1)
        A1 = "NVR_Username,':',cRealm,':',NVR_Password"
        A2 = "'GET:',cURI"
        fnGenRandom()
        MD5(A1,HA1)
        MD5(A2,HA2)
        TEMP = "HA1,':',cNonce,':',cQop,':',HA2"
        MD5("HA1,':',cNonce,':00000001:',cCNonce,':',cQop,':',HA2",Response)
        CLEAR_BUFFER CnvrBuffer
        fnSendResponse()
        } 
    }
    
Sign In or Register to comment.