Documenting the ToupCam wireless protocol

[ToupTek] makes some nice microscope cameras. For my integrated circuit imaging microscope, I wanted to move away from my current Canon DSLR, which has survived a few tens of thousands of mechanical shutter release activations, so I'd like a cheaper backup.

 Canon Rebel T3i mounted on my Olympus trinocular BHMJ metallurgical microscope.

Canon Rebel T3i mounted on my Olympus trinocular BHMJ metallurgical microscope.

 I used a generic [ NDPL-2 (2x) adapter ]. It was quite loose and didn't even come with an O-ring, so I just hot-glued the thing. Even then it was a little wobbly so I put some paper shims in there with the glue. Surprisingly, the images come out almost, but not quite, perpendicular to the light path.

I used a generic [NDPL-2 (2x) adapter]. It was quite loose and didn't even come with an O-ring, so I just hot-glued the thing. Even then it was a little wobbly so I put some paper shims in there with the glue. Surprisingly, the images come out almost, but not quite, perpendicular to the light path.

AmScope has [a wireless camera] which seems to perform well. A little research showed that AmScope basically sells rebranded cameras from [ToupTek]. Even AmScope's camera software and microscope camera adapters are just rebranded.

 AmScope's HD205-WU camera. It is a rebranded [ T  oupTek X  CAM1080PHB ]. You also need the adapter, [ AmScope RU050 ], or [ ToupTek FMA050 ].

AmScope's HD205-WU camera. It is a rebranded [ToupTek XCAM1080PHB]. You also need the adapter, [AmScope RU050], or [ToupTek FMA050].

Now, the camera doesn't have a convenient logic level trigger input like the DSLR does, so I need some way of triggering the camera. The camera, which I'll start calling ToupCam, has a WiFi interface, a USB interface, an HDMI interface, and an SD card slot.

 ToupCam mounted on an AmScope inspection microscope, showing the HDMI output. Yes, that's a mouse cursor in the top part of the "E".

ToupCam mounted on an AmScope inspection microscope, showing the HDMI output. Yes, that's a mouse cursor in the top part of the "E".

The USB interface is, in fact, just a USB port. You can either plug in a mouse or the included WiFi USB dongle. With the mouse, you can move the cursor around and pull up the native interface on the HDMI monitor. With the WiFi dongle attached, the camera presents itself as an Access Point.

If you connect your computer's WiFi to that access point, you can then run ToupTek's ToupView (AmScope's AmScope) software, and it will find the camera. You can then control the camera from the software.

There's just one problem. If your computer is connected to the camera's WiFi AP, you can't connect to the Internet. Maybe if you had two WiFi adapters you could do it, but then you'd have to be sure to route Internet traffic to your Internet-connected adapter.

 I had no Internet access when I took this screenshot.

I had no Internet access when I took this screenshot.

So the camera sends live video, and can also send a "snap" (i.e. higher-resolution image). You can also send it commands changing various controls such as exposure.

Now, ideally, I'd like to connect to this camera using the BeagleBone Black that I already use to control the microscope stage and the camera trigger, and save the images to an SD card. However, the WiFi protocol is undocumented.

Luckily, WireShark can show me the WiFi packets.

wireshark-toupcam-connect.JPG

192.168.7.1 is the camera, and 192.168.7.2 is the address the camera gave to my computer. We can see that video is sent from the camera to the computer via the RTP protocol. It appears the camera looks like an ordinary IP camera accessible through an RTSP URL.

Of course, I don't care about video unless I want to display the video via the BBB, which could be convenient for focusing. What I really want to do is (a) get an image and (b) adjust controls.

So, I hit the Snap button and see what happens...

wireshark-toupcam-snap.JPG

Apparently snapping an image involves connecting to port 555 and sending this package that starts with "GE".

The response appears to be a GE reply, with a jpg file in there somewhere.

 The red portion is the request, the blue portion is the response. I've highlighted the beginning of the jpg file.

The red portion is the request, the blue portion is the response. I've highlighted the beginning of the jpg file.

Also note that there's a suspicious-looking "GEPJ" backwards "JPEG" in there. The 0x001E1E29 just prior to the JPG file appears to be the size of the enclosed JPG file, which goes from offset 0x6D to 0x1E1E95.

There's also another length before that, 0x001E1E3A, so it appears there's yet another wrapper, and a 0x001E1E4A before even that, so yet another layer of wrappers.

We don't really care about the details of these wrappers, just that they exist and can be used to get to the actual JPG file content.

Now, in terms of the controls, here's what happened when I fiddled around with the exposure setting:

wireshark-toupcam-exposure.jpg

From what I can tell, ToupCam is using the [Connectionless Network Protocol] (CLNP) to port 12000. The only thing I recognized in the data field is 0xB4 (180), which is what the exposure value is.

The rest of the CLNP packets come from the ToupCam itself, and appear to indicate the current settings of everything. What these settings are, I don't know. But in the data above, it appears that 03 is like a register number, 04 never changes so could be a payload length, and then 000000B4 is the data.

Here's the data for the CLNP packet coming back from the ToupCam reporting the exposure value: 00 00 00 00 02 03 04 00 00 00 B4. That 03 is in the position that changes for the CLNP packets from ToupCam, along with the last two bytes, so is probably a register number. For example, for register 01, the value is E290 (58000), a suspiciously round number. Color temperature in 1/10 K? Register 0A contains 2BC (700), another round number. There's a gamma setting of 7.00 that might be this register.

So the next step is to write a simple program which attempts to connect to the camera, pull a still image, and modify some values.