Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Motion Detection and MQTT #78

Closed

Conversation

QuantumEntangledAndy
Copy link
Collaborator

@QuantumEntangledAndy QuantumEntangledAndy commented Sep 25, 2020

This is more of a proposal for comments than something I want to merge just yet, but we can do motion detection event publishing using MQTT.

Currently I have:

  • Gotten the MQTT server up and running
  • Added the BC message ID num 33
  • Tried to subscribe to both message 3 and 33

The subscription to both 3 and 33 is not quite working as expected but I am working on it

Works towards #58


Update: This started off as just a simple motion detection and MQTT however in the process it was found that our undestanding of the protocol needed updating and that the bc_protocol and the serde needed updating. Sorry for that...

@QuantumEntangledAndy QuantumEntangledAndy marked this pull request as draft September 25, 2020 08:54
@QuantumEntangledAndy
Copy link
Collaborator Author

@thirtythreeforty So I am currently trying to get neolink to pick up the motion messages with id =33 and could use some advice if you are free

If I run wireshark with the official client

  • The cam sends 33 motion messages whenever it detects motion status change but otherwise no other messages on 33

If I run with neolink

  • No messages with id 33 are sent ever

I think there may be some sort of send me motion please being issues by the client but when I read all message that the official client send there is nothing obvious. Is there anything you can think of?

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 26, 2020

Offical client sends:

  • 1: Login legacy
  • 1: Login modern
<?xml version="1.0" encoding="UTF-8" ?>
<body>
<LoginUser version="1.1">
<userName>...</userName>
<password>...</password>
<userVer>1</userVer>
</LoginUser>
<LoginNet version="1.1">
<type>LAN</type>
<udpPort>0</udpPort>
</LoginNet>
</body>
  • 151: Ability Support
<?xml version="1.0" encoding="UTF-8" ?>
<Extension version="1.1">
<userName>...</userName>
</Extension>
  • 104: Legacy Unknown
  • 199: Legacy Unknown
  • 115: Legacy Unknown
  • 10: Unknown XML
<?xml version="1.0" encoding="UTF-8" ?>
<Extension version="1.1">
<channelId>0</channelId>
</Extension>
  • 190: Unknown XML
<?xml version="1.0" encoding="UTF-8" ?>
<Extension version="1.1">
<channelId>0</channelId>
</Extension>
  • 115: Legacy Unknown
  • 4: Unknown (seems to be preview) XML
<?xml version="1.0" encoding="UTF-8" ?>
<body>
<Preview version="1.1">
<channelId>0</channelId>
<handle>0</handle>
</Preview>
</body>
  • 2: XML Unknown (seems to be some sort of login)
<?xml version="1.0" encoding="UTF-8" ?>
<body>
<LoginUser version="1.1">
<userName>...</userName>
<password>...</password>
<userVer>1</userVer>
</LoginUser>
</body>

@QuantumEntangledAndy
Copy link
Collaborator Author

These are matched pairs of client send, cam reply

  • Client 58
<?xml version="1.0" encoding="UTF-8" ?>
<Extension version="1.1">
<userName>...</userName>
</Extension>
  • Cam 58
<?xml version="1.0" encoding="UTF-8" ?>
<body>
<AbilitySuppport version="1.1">
<userName></userName>
<system>1</system>
<streaming>1</streaming>
<record>1</record>
<network>1</network>
<PTZ>1</PTZ>
<IO>0</IO>
<alarm>1</alarm>
<image>1</image>
<video>1</video>
<audio>1</audio>
<security>1</security>
<replay>1</replay>
<disk>1</disk>
</AbilitySuppport>
<UserList version="1.1">
<User>
<userId>0</userId>
<userName>...</userName> <!-- User and pass completly plain text! -->
<password>...</password>
<userLevel>1</userLevel>
<loginState>0</loginState>
<userSetState>none</userSetState>
</User>
<User>
<userId>0</userId>
<userName>...</userName>
<password>...</password>
<userLevel>0</userLevel>
<loginState>0</loginState>
<userSetState>none</userSetState>
</User>
<User>
<userId>0</userId>
<userName>...</userName>
<password>...</password>
<userLevel>1</userLevel>
<loginState>1</loginState>
<userSetState>none</userSetState>
</User>
</UserList>
</body>

Seems to reply with users capabilities and a full list of other user with passwords (I am hoping the full list is only when admin but even so...)

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 27, 2020

  • Client 199 Legacy
0000   f0 de bc 0a c7 00 00 00 00 00 00 00 00 00 00 02
0010   00 00 14 64 00 00 00 00
  • Cam 199 XML
<?xml version="1.0" encoding="UTF-8" ?>
<body>
<Support version="1.1">
<IOInputPortNum>0</IOInputPortNum>
<IOOutputPortNum>0</IOOutputPortNum>
<diskNum>0</diskNum>
<channelNum>1</channelNum>
<audioNum>1</audioNum>
<ptzMode>pt</ptzMode>
<ptzCfg>0</ptzCfg>
<B485>0</B485>
<autoUpdate>0</autoUpdate>
<pushAlarm>1</pushAlarm>
<ftp>0</ftp>
<ftpTest>1</ftpTest>
<email>1</email>
<wifi>5</wifi>
<record>0</record>
<wifiTest>1</wifiTest>
<rtsp>0</rtsp>
<onvif>0</onvif>
<audioTalk>1</audioTalk>
<rfVersion>0</rfVersion>
<rtmp>0</rtmp>
<noExternStream>1</noExternStream>
<timeFormat>1</timeFormat>
<ddnsVersion>1</ddnsVersion>
<emailVersion>3</emailVersion>
<pushVersion>1</pushVersion>
<pushType>1</pushType>
<audioAlarm>1</audioAlarm>
<apMode>0</apMode>
<cloudVersion>30</cloudVersion>
<replayVersion>1</replayVersion>
<mobComVersion>0</mobComVersion>
<syncTime>1</syncTime>
<netPort>1</netPort>
<videoStandard>0</videoStandard>
<smartHome>
<version>1</version>
<item>
<name>googleHome</name>
<ver>1</ver>
</item>
<item>
<name>amazonAlexa</name>
<ver>1</ver>
</item>
</smartHome>
<item>
<chnID>0</chnID>
<ptzType>3</ptzType>
<ptzPreset>0</ptzPreset>
<ptzPatrol>0</ptzPatrol>
<ptzTattern>0</ptzTattern>
<ptzControl>0</ptzControl>
<rfCfg>0</rfCfg>
<noAudio>0</noAudio>
<autoFocus>0</autoFocus>
<videoClip>0</videoClip>
<battery>0</battery>
<ispCfg>0</ispCfg>
<osdCfg>1</osdCfg>
<batAnalysis>0</batAnalysis>
<dynamicReso>0</dynamicReso>
<audioVersion>15</audioVersion>
<ledCtrl>1</ledCtrl>
<motion>1</motion>
</item>
</Support>
</body>

Seems to be a list of things the camera can do

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 27, 2020

  • Client 115 Legacy
0000   f0 de bc 0a 73 00 00 00 00 00 00 00 00 00 00 0e
0010   00 00 14 64 00 00 00 00
  • Cam 115 XML
<?xml version="1.0" encoding="UTF-8" ?>
<body>
<WifiSignal version="1.1">
<signal>-40</signal>
</WifiSignal>
</body>

Seems to be a send reply on signal strength

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 27, 2020

The following do not seem to have a reply from the camera

  • 90
<?xml version="1.0" encoding="UTF-8" ?>
<Extension version="1.1">
<channelId>0</channelId>
</Extension>

One of this might request the motion stream

@QuantumEntangledAndy
Copy link
Collaborator Author

  • Client 104
0000   f0 de bc 0a 68 00 00 00 00 00 00 00 00 00 00 0a
0010   00 00 14 64 00 00 00 00
  • Cam 104
<?xml version="1.0" encoding="UTF-8" ?>
<body>
<SystemGeneral version="1.1">
<timeZone>-25200</timeZone>
<osdFormat>DMY</osdFormat>
<year>2020</year>
<month>9</month>
<day>27</day>
<hour>16</hour>
<minute>18</minute>
<second>9</second>
<deviceId>0</deviceId>
<timeFormat>0</timeFormat>
<language>English</language>
<deviceName>Cammy02</deviceName>
</SystemGeneral>
<Norm version="1.1">
<norm>NTSC</norm>
</Norm>
</body>

Seems to be camera timezone info

@QuantumEntangledAndy
Copy link
Collaborator Author

  • Client 10
<?xml version="1.0" encoding="UTF-8" ?>
<Extension version="1.1">
<channelId>0</channelId>
</Extension>
  • Cam 10
<?xml version="1.0" encoding="UTF-8" ?>
<body>
<TalkAbility version="1.1">
<duplexList>
<duplex>FDX</duplex>
</duplexList>
<audioStreamModeList>
<audioStreamMode>followVideoStream</audioStreamMode>
</audioStreamModeList>
<audioConfigList>
<audioConfig>
<priority>0</priority>
<audioType>adpcm</audioType>
<sampleRate>16000</sampleRate>
<samplePrecision>16</samplePrecision>
<lengthPerEncoder>1024</lengthPerEncoder>
<soundTrack>mono</soundTrack>
</audioConfig>
</audioConfigList>
</TalkAbility>
</body>

This is the back channel audio I think where we can send sound to play at the camera

@twistedddx
Copy link
Contributor

twistedddx commented Sep 27, 2020

token

I see the official client shot of this packet which may be the trigger for alarm messages?
<?xml version="1.0" encoding="UTF-8" ?> <Extension version="1.1"> <userName>admin</userName> <token>system, network, alarm, record, video, image</token> </Extension>

@QuantumEntangledAndy
Copy link
Collaborator Author

Interesting. I haven't seen that packet but sometimes I miss other packets too so maybe the Mac packet taping method isnt reliable. Could you post the part with the BC packet header. It's a little difficult to read in your picture.

@twistedddx
Copy link
Contributor

0000 xx xx xx xx xx xx xx xx xx xx xx xx xx xx 45 00
0010 01 76 8c 46 40 00 80 06 00 00 ac 10 19 7f ac 10
0020 19 02 f6 72 23 28 15 d6 f2 52 43 87 9a 7d 50 18
0030 10 0a 8c 0a 00 00 f0 de bc 0a 92 00 00 00 00 00
0040 00 00 00 00 00 04 00 00 14 64 00 00 00 00 f0 de
0050 bc 0a c0 00 00 00 00 00 00 00 00 00 00 05 00 00
0060 14 64 00 00 00 00 f0 de bc 0a 1f 00 00 00 00 00
0070 00 00 00 00 00 05 00 00 14 64 00 00 00 00 f0 de
0080 bc 0a 85 00 00 00 00 00 00 00 00 00 00 06 00 00
0090 14 64 00 00 00 00 f0 de bc 0a 50 00 00 00 00 00
00a0 00 00 00 00 00 07 00 00 14 64 00 00 00 00 f0 de
00b0 bc 0a 72 00 00 00 00 00 00 00 00 00 00 08 00 00
00c0 14 64 00 00 00 00 f0 de bc 0a 97 00 00 00 a6 00
00d0 00 00 00 00 00 02 00 00 14 64 a6 00 00 00 3c 3f
00e0 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30
00f0 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 46 2d
0100 38 22 20 3f 3e 0a 3c 45 78 74 65 6e 73 69 6f 6e
0110 20 76 65 72 73 69 6f 6e 3d 22 31 2e 31 22 3e 0a
0120 3c 75 73 65 72 4e 61 6d 65 3e 61 64 6d 69 6e 3c
0130 2f 75 73 65 72 4e 61 6d 65 3e 0a 3c 74 6f 6b 65
0140 6e 3e 73 79 73 74 65 6d 2c 20 6e 65 74 77 6f 72
0150 6b 2c 20 61 6c 61 72 6d 2c 20 72 65 63 6f 72 64
0160 2c 20 76 69 64 65 6f 2c 20 69 6d 61 67 65 3c 2f
0170 74 6f 6b 65 6e 3e 0a 3c 2f 45 78 74 65 6e 73 69
0180 6f 6e 3e 0a

There is several magic's in there.

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 27, 2020

How interesting multiple magics... Neolink is not designed to send Extension XML let alone multiple headers. This will need some doing to test out.

I wonder if it is one header per requested token in the extension. Seems to be 6 headers and 6 tokens. If we can do the same with just one header one token XML that would be easier.

@twistedddx
Copy link
Contributor

twistedddx commented Sep 27, 2020

This is that packet going to a Reolink RLC-410

The dissector doesn't like this packet and is likely why you miss it.
token2

@twistedddx
Copy link
Contributor

RLC-410 4mp version (encrypted):
0000 xx xx xx xx xx xx xx xx xx xx xx xx xx xx 45 00
0010 01 52 92 7f 40 00 80 06 00 00 ac 10 19 7f ac 10
0020 19 06 c8 ff 23 28 40 78 00 a2 c6 8a 48 5a 50 18
0030 02 01 8b ea 00 00 f0 de bc 0a c0 00 00 00 00 00
0040 00 00 00 00 00 05 00 00 14 64 00 00 00 00 f0 de
0050 bc 0a 1f 00 00 00 00 00 00 00 00 00 00 05 00 00
0060 14 64 00 00 00 00 f0 de bc 0a 85 00 00 00 00 00
0070 00 00 00 00 00 06 00 00 14 64 00 00 00 00 f0 de
0080 bc 0a 66 00 00 00 00 00 00 00 00 00 00 07 00 00
0090 14 64 00 00 00 00 f0 de bc 0a 50 00 00 00 00 00
00a0 00 00 00 00 00 08 00 00 14 64 00 00 00 00 f0 de
00b0 bc 0a 72 00 00 00 00 00 00 00 00 00 00 09 00 00
00c0 14 64 00 00 00 00 f0 de bc 0a c7 00 00 00 00 00
00d0 00 00 00 00 00 02 00 00 14 64 00 00 00 00 f0 de
00e0 bc 0a 3a 00 00 00 6a 00 00 00 00 00 00 03 00 00
00f0 14 64 6a 00 00 00 23 12 44 26 36 49 0e 9a 6d 5e
0100 55 24 34 54 5a ce 31 1d 1e 6b 3f 07 1b 90 7b 44
0110 52 2c 67 4b 2d ab 59 00 04 69 7a 56 46 f5 23 68
0120 44 3f 3f 07 0b 96 70 43 1c 3d 3f 1b 0b 96 70 43
0130 01 69 6b 47 49 dd 21 27 00 3e 29 0c 0a b1 7e 40
0140 59 75 3b 0d 15 96 71 11 13 3e 29 0c 0a b1 7e 40
0150 59 75 50 55 57 ba 67 59 59 25 29 00 17 91 21 27

@QuantumEntangledAndy
Copy link
Collaborator Author

I have found a few moer seems the dissector won't spot multiple header packets. Thanks for the heads up maybe I can make the dissector look for array of headers

@QuantumEntangledAndy
Copy link
Collaborator Author

I've modified the dissector to find multi header packets. Still not perfect as I can see more packets (single header) that haven't been picked up either. I am wondering if the cam is just bundling some messages together of if it's supposed to be these header all share the same XML data

@QuantumEntangledAndy
Copy link
Collaborator Author

You know how we had to make the media packets a stream that could cross packet boundaries. I am thinking that all of the BC packets are an embedded stream....

@QuantumEntangledAndy
Copy link
Collaborator Author

@thirtythreeforty Do you think it is possible that it is not just the media packets that are an embedded stream but all messages?

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 28, 2020

So my dissector now reassebles over packets and that causes it to fully build the media packets as one set and for it to break at the reassembled bounaries. I have also had some cases where a new message starts right after an old one without a packet brake (first message modern with xml second video mesage)

@QuantumEntangledAndy
Copy link
Collaborator Author

I think the encryption flag is not what we think it is

This packet

0000   f0 de bc 0a be 00 00 00 68 00 00 00 00 00 00 0e
0010   00 00 14 64 68 00 00 00 23 12 44 26 36 49 0e 9a
0020   6d 5e 55 24 34 54 5a ce 31 1d 1e 6b 3f 07 1b 90
0030   7b 44 52 2c 67 4b 2d ab 59 00 04 69 7a 56 46 f5
0040   23 68 44 3f 3f 07 0b 96 70 43 1c 3d 3f 1b 0b 96
0050   70 43 01 69 6b 47 49 dd 21 27 00 28 32 08 16 91
0060   7a 41 75 2f 64 59 44 d0 7c 45 5d 25 34 0c 14 b6
0070   7b 13 36 77 75 2c 00 8b 7a 43 4f 22 35 07 46 f5

Has an encryption flag as false, BUT it is clearly encrypted xml

@twistedddx
Copy link
Contributor

Maybe the encryption flag is another layer of obfuscation.
It is just to throw you off?

The person that invented the protocol which tries to hide the username and password with md5 and nonce etc.
But then sends the username and password in cleartext 5 seconds later, could have also decided an encrypted flag that rarely actually shows the correct value will confuse someone that was eaves dropping.

If you didn't see the initial correct encrypted status you would need to test a packet for if the xml portion looked like <?xml or other instead of simply looking at the encrypted flag.

Or the encrytped flag is only ever actually set by the cam in its first response.
All other messages are hardcoded and the encrypted flag is just a hangover of whatever the dev's copy/paste had?

@QuantumEntangledAndy
Copy link
Collaborator Author

baichuan.lua.zip

Here is my updated dissector maybe you can have a go and see if it behaves for you. It seems to work for me to pick up multi messages per packet and will also still try and reassemble messages split over multiple packets

@QuantumEntangledAndy
Copy link
Collaborator Author

It also will always test the first four bytes of the xml to see if its encrypted <?xml and then decrypt if neccecary.

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 29, 2020

I get this message you do now

  • 151
<?xml version="1.0" encoding="UTF-8" ?>
<Extension version="1.1">
<userName>...</userName>
<token>system, network, alarm, record, video, image</token>
</Extension>

yay will keep looking into the packets and then test various things

@QuantumEntangledAndy
Copy link
Collaborator Author

This is the reply to 151 from the camera

<?xml version="1.0" encoding="UTF-8" ?>
<body>
<AbilityInfo version="1.1">
<userName>...</userName>
<system>
<subModule>
<abilityValue>general_rw, norm_rw, version_ro, uid_ro, autoReboot_rw, restore_rw, reboot_rw, shutdown_rw, dst_rw, log_ro, performance_ro, upgrade_rw, export_rw, import_rw, bootPwd_rw</abilityValue>
</subModule>
</system>
<network>
<subModule>
<abilityValue>port_rw, dns_rw, email_rw, ipFilter_rw, localLink_rw, pppoe_rw, upnp_rw, wifi_rw, ntp_rw, netStatus_rw, ptop_rw, autontp_rw</abilityValue>
</subModule>
</network>
<alarm>
<subModule>
<channelId>0</channelId>
<abilityValue>motion_rw</abilityValue>
</subModule>
</alarm>
<image>
<subModule>
<channelId>0</channelId>
<abilityValue>ispBasic_rw, ispAdvance_rw, ledState_rw</abilityValue>
</subModule>
</image>
<video>
<subModule>
<channelId>0</channelId>
<abilityValue>osdName_rw, osdTime_rw, shelter_rw</abilityValue>
</subModule>
</video>
</AbilityInfo>
</body>

Seems to be a list of capabilities for the requested tokens

@twistedddx
Copy link
Contributor

twistedddx commented Sep 29, 2020

baichuan.zip

Love the updated dissector.
Attached are my changes to the dissector
Adds XML dissector in a few places, adds an extra message type and adds few comments. Although I just realised my comment for messageLen * 2 is wrong, I simply miss counted the bytes.

I'm sure some coder will yell and say we should version control these changes and not just attach random zip's!

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 29, 2020

Haha yes don't worry it is version controlled in this branch just hasent been pushed yet. I add the extra XML and a few changes he's myself right after I sent the zip.

Ill merge your zip changes in too (I wonder if I can commit your changes under your name... version control expert will probably tell me theres a way to send diffs with names and commit messages too) correct method is probably to make a PR against my branch

@QuantumEntangledAndy
Copy link
Collaborator Author

I'm going to try and write up and markdown file that contains example messages that Ive seen and add those too. Might help me find the way to start the motion if I have them all layed out.

@QuantumEntangledAndy
Copy link
Collaborator Author

QuantumEntangledAndy commented Sep 30, 2020

So I have added a documentation with all the messages I observed during normal operation. This does not change any settings or anything special just connect and watch what was sent between client and camera. You can see the current version here

QuantumEntangledAndy and others added 15 commits August 5, 2021 07:46
Added a reboot command to neolink
Split bc and bcmedia into seperate modules

Add bcmedia serialisation and remove redundent data from the bcmedia model
Bug fix to TalkConfig

Bug fix to adpcm serde

Slow talk to sample rate

Update gstreamer-rs

Also remove gio and glib in favor of gstreamer::{glib, gio} to ensure 
always using comapt version

Add TalkAbility protocol and update talk to use it. Also add a `talk_stream` method

Use `talk_stream` and gstreamer to play other types of audio

Add microphone and volume to talk command

Don't decode adpcm

Debug print the error when camera fails to stream

Use correct adpcm block size

Allow retries during read in deserlisation

Use TalkReset messages after talk finishes
Update talk sources to use new input format
Quick fix to input sources
@PieterGit
Copy link

@QuantumEntangledAndy Can you indicate the state of Motion Detection and MQTT. I had some compile errors on your mqtt branch with cargo build (of #58 ). Can you indicate what's the best way to help and if I should use your master branch or the mqtt branch to go forward with this.

I would like this functionality to be able to send a motion on/off commands from the neolink to Motioneye. On the Motion/MotionEye side, it probably also needs some work to get motion(eye) to react on these (MQTT) commands.

@QuantumEntangledAndy
Copy link
Collaborator Author

mqtt is still not in master. If #185 gets merged I will add it as a formal extension using sub commands. If I get time I'll try and see if I can get this branch to compile for you

@PieterGit
Copy link

@QuantumEntangledAndy thanks for the quick reply. I managed to compile the mqtt branch of (#58 ) by applying this working workaround: rust-lang/rust#81654 (comment) . It seems upstream lexical-core library has an issue. I managed to use lexical-core 0.7.6 and then the branch compiles and works. I will try to get Motion(eye) respond to these messages.

@QuantumEntangledAndy
Copy link
Collaborator Author

The lexical core issue is already fixed in master. I just need to bring this mqtt up to date. I am going to add it as a subcommand to the #185 so it will be useable as

neolink mqtt --config=...

Might take a week though as I've got a few work commitments coming up.

@PieterGit
Copy link

PieterGit commented Aug 9, 2021

Don't hurry. I will do my testing now with the mqtt branch. I will add some documentation and scripts on how to combine it with Motioneye, to use the http://localhost:7999/0/config/set?emulate_motion=on|off to trigger the motion commands to Motioneye. I got that working, but needs more robustness and cleaner scripts. Perhaps I can upgrade it to neolink motion -config=... if #185 is done.

@QuantumEntangledAndy
Copy link
Collaborator Author

Ok so I have something if you want to test it out. This branch of mqtt is used like this

neolink mqtt --config=config.toml

The motion and status messages from the camera to the mqtt are the same.

There are the following mqtt control commands from mqtt to the camera

  • neolink/camname/control/led: on/off
  • neolink/camname/control/ir: on/off/auto
  • neolink/camname/control/reboot: <message value ignored>

@QuantumEntangledAndy
Copy link
Collaborator Author

Closed in favor of #197

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants