Reverse engineering carelink usb

I've just started to play around with trying to get the Carelink USB device to work under Linux. I've grown tired of having to have an XP box laying around just so I can run that crappy Java app from minimed. I haven't done much other than capture the usb session in windows and replay parts of it under linux. It looks as though the serial number is used in each transaction with some data appended to it. Also looks as though every command is repeated 3 times, can't hurt right? Right now I can pretty much only get the pump to suspend, and then resume.

My goal is to have a faster application that can run on pretty much any OS. Right now I'm using libusb which should help keep the nasty USB part of the app somewhat simple. Has anyone else done anything like this? I'd hate to be reinventing the wheel.

*Disclaimer*

I'm only donig this on a spare pump. I'd never think of doing this on my active pump, that might void the warranty.

Hi !
I am Andy, I am developer on GGC project (ggc.sourceforge.net). I have started working on support for Minimed, but since I don’t own one, it’s getting along very slowly (I remotely connect to my friend to test, but since I don’t have that much time, work is progressing slowly). We are currently working on support through COM cable, since USB will bring out some other problems, although, if Carelink USB device is detected as ttyUSB, it might not even be a problem (we can detected ttyUSB in rxtx library we use).
Please contact me in Private Message if you wish to colaborate a little… If you wish to make it usable for everybody (any OS) then Java will be your solution (as is GGC)

Take care for now,
Andy

P.S.: Reading from device should be able to make any damage, but writing to it might (you might change configuration).

An open source project would be great. I think many more pumpers would use our project Glucosurfer to exchange and discuss their latest data in full anonymity with the Tu community. It is just the complicated approach via Carelink that makes it very unpleasant: open carelink, sync the pump, export as csv file, import into Glucosurfer. Sadly I have no pump at hand so I can not support your project with some reverse engineering.

Hi Holger !
I was already thinking about your solution to implement it in GGC. So I asked MM to just give me few pointers, what each value means, and they replied that they will do that, but after that there was no word (I tried to contact them twice after that). They are very uncooperative…
I have already talked with company that sells MM here in Slovenia, and we had everything worked out, they were just waiting for confirmation from MM USA, if we can do that, but we got a RED light, so work crawled to stop… As I am not owner of Minimed pump its much harder to do this… I our country we don’t get 2 pumps, so nobody can borrow me his replacement (since we don’t have them).
Problem is that using export file would again work for people who have windows and can upload data to carelink server.
Andy

I totally agree with the whole “Grown tired of having to have an XP box laying around just so I can run that crappy Java app from minimed”

I have only had a pump for about a month now but find the fact that I have to be in IE just to use the “webapp” quite silly. In my opinion a webapp should be accessible from any browser on any OS including mobile devices. there has to be a way to make the webpage think you are using IE on a windows box. All I want to do is to liberate my data from their ugly GUI and build my own diabetes dashboard that I can share with whomever I want and access it from any machine anywhere in the world.

If anyone gets this working on Linux or even for Mac please let me know, I am very interested in this.

I’ve made some progress on this. I’m close, but I need some help deciphering what I’m looking at. Here’s a log of my library talking to the pump: https://bitbucket.org/bewest/carelink-python/src/tip/megalog . I’d like to publish an open source library containing implementations for many devices. I’ve got several Lifescan devices working, but the usbstick/pump protocol is difficult without a spec sheet.

The library will be focused on talking to these devices, and it’ll be in python at first. Python will make the code flexible and easy to document. If someone could help review the protocol, I’d be grateful, especially if you can explain what I’m doing wrong here.

The log shows successfully using the local usb commands to initialize comms with a pump, and an attempt to use one of the remote data commands. The use remote data commands involve asking the status of the tx buffer for the length of the available message. The length are supposed to be the 7th and 8th bytes in the usb status commands ( [0x03] ), but for some reason I’m unable to get anything but some error code. Unfortunately, I’m not sure how to interpret the error bytes I’m getting, although the get interface stats command do show a tx command sequence counter incrementing.

Communication with Carelink is not that simple. You don-t just give command and get data… You need to do a handshape, and every time you send command, command is encrypted (ok not always, but at least at handshake commands). Command that you send to device is I think that about 16 characters long (maybe more) and it contains your serial number. Each command will have your serial number embeded, and return data also. Protocol is quite complicated, but even if you could get to data, data is somehow encoded in some proprieatry binary format. If you need more info, I have some java code which you could look through too see if it helps…
Andy

Yeah, I think I understand the basics, my problem is that something about my handshaking is wrong. I can decode the binary format, but I’m having trouble understanding where in the handshake flows I’m going wrong.



Where’s your java source?


               pc      usb                    |       |       
This is kind of a "send command" command.
write          |------>|      Hint: code is 14th byte
               |       |      (bytes[13])
read           |<------|       success [ 0x01, 0x85 U, ?? ]
               |       |       fail [ 0x01, 0x85 f, ?? ]
write          |------>|      code=[ 0x03 ] usb status command
repeat         |       |<     Continually ask for the usb
               |       |                  status until the stick
               |       |                  indicates that we are done
               |       |                  receiving and we have a length.
read           |<------|      success [ 0x01, 0x85 U, ?? ]
               |       |      fail    [ 0x01, 0x66 f, ?? ]
read           |<------|      tx.stats = bytes[5]
read           |<------|      length = bytes[6..8]
format         |<      |      Then use the length to format the
               |       |                flush command, which will give us
               |       |                the contents of radio buffer.
write          |------>|      command [ 0x0C, 0x00, 0x00,
               |       |                  HighByte(length),
               |       |                  LowByte(length), CRC ]
read           |<------|      read data in 64 byte chunks until we've got
               |       |      the amount of data we expected

Init radio: https://bitbucket.org/bewest/carelink-python/src/tip/a.py#cl-254
Send Data Command: https://bitbucket.org/bewest/carelink-python/src/tip/a.py#cl-37
Get tx status/length: https://bitbucket.org/bewest/carelink-python/src/tip/a.py#cl-118
https://bitbucket.org/bewest/carelink-python/src/tip/src/i...
Retrieve Data Command: https://bitbucket.org/bewest/carelink-python/src/tip/src/insulaudit...

I think I'm really close. I can watch the tx transmit packet count go up, but I'm only getting error bytes, not the expected length and status bytes when I poll for tx status / length. Any ideas?
-bewest

Andy,

I’ve been studying the applet if that’s what you are referring to. I believe I’ve implemented something close to what’s found in the applet. EG, inputs matching the deciphered inputs to build a command match the byte sequences found in the logs.

My own java source is not ready yet. I started working on it, but since I don-t own MM pump I couldn-t test it… Preliminary testing with friends device (and my code) were not that good. I am waiting for friend to lend me his pump, after he gets new one… For my testing I used serial port cable, since this is the one I have. For sources contact me offline.
Andy

Andy, how do I contact you?

My email username is bewest and my email provider is gmail. I can help test and develop the protocol. Where are you located? I’m in San Francisco, CA. We should collaborate on some compatible test suites.

You don't need libusb, you just need any the generic usbserial driver (on linux) to be inserted with the vendor and product tags of the usb device.

The protocol is actually two protocols stacked on top, on synchronous protocol with the usb stick, which is used to control asynchronous communication with the pump.

I managed to build a python library which demonstrates how to use the protocol. You can see example output here:
https://github.com/bewest/decoding-carelink/blob/rewriting/analysis/bewest-pump/ReadHistoryData-page-25.data.list_opcodes.markdown#record-4-unabsorbedinsulinbolus-unknown-head14-body0-op0x5c

If you've ever wondered what "unabsorbed total" really means (it must sometimes consist of multiple doses), this information is actually available in the pump's logs, as demonstrated in the link above.


DECODED

[{'age': 49, 'amount': 0.75, 'curve': 4},
{'age': 59, 'amount': 1.95, 'curve': 4},
{'age': 33, 'amount': 1.8, 'curve': 20},
{'age': 223, 'amount': 2.85, 'curve': 20}]

I imagine that being able to visualize which portions of which doses are active, and where they are in each of their curves while dosing will help eliminate adverse reactions.

We've demonstrated how to perform this by forwarding the entire usb stick communication portion over the internet, to a server under my control at bewest.io. We'll be using d3.js to visualize the history of the pump, any bl.ocks.org contributions, patches, test runs welcome! (We could use some help finishing identifying dual bolus records, etc).

Eventually, we'll post instructions for DIY-mobile auditing device, taking shape here: https://github.com/bewest/insulaudit/tree/master/hacking

Howdy all,

I've made some progress on the protocol handling. You can now press buttons, set temporary basal rates, and suspend-resume.

https://github.com/bewest/decoding-carelink

Hopefully this will help people more easily maintain their pumps, eg, updating the clocks to get accurate dates and times. Hopefully it will also help educate on what is possible when patients can truly own and control their devices.

Here's a video showing a potential use case for this kind of thing:
https://www.youtube.com/watch?v=sqyPGrqnxOY&feature=youtu.be

Impressive work.

Medtronic is now phasing in MiniMed 640G insulin pump in connection with the CONTOUR NEXT LINK 2.4 meter from Bayer. The meter also acts as the USB connectivity device. It would be interesting to see if this is an advantage or disadvantage for making the Carelink platform Linux compatible.

https://www.medtronic-diabetes.co.uk/minimed-system/minimed-640g-system.