Take the 2-minute tour ×
Reverse Engineering Stack Exchange is a question and answer site for researchers and developers who explore the principles of a system through analysis of its structure, function, and operation. It's 100% free, no registration required.

In hope this is appropriate

I have a Bosch Tassimo TAS2002EE coffee maker that uses T-Disks. Those contain coffee/milk/something else, and a barcode that is supposed to tell the machine how to deal with the disk.

What I want to do is undertand the barcode amd come up with some different barcodes that would be accepted as valid and let me adjust e.g. drink volume.

At first I wasn't able to find any decent information about these barcodes, among the top Google hits were things like this rather useless rant. Surprisingly, when searching for pictures of T-Disks (in order to study more barcodes), I stumbled upon this useful post: Hacking the Tassimo - Part 2: Breaking the Code, which also links to this T-Disk-related patent, in which there is a table explaining the controlling bits. While this was quite promising, it resulted in nothing, as the blog author found out himself, too.


On top of the information from the links above, here's what I found out myself.

The barcode uses the Interleaved 2 of 5 symbology and 6 digits. The last digit is the check digit calculated according to the UPC Check Digit rules.
Actual barcodes with the checksum removed:

╔═════════╦══════════════════════════════════╦════════════╦═══════════════════╗
║ Barcode ║ Product                          ║ Output, ml ║ Barcode binary    ║
╠═════════╬══════════════════════════════════╬════════════╬═══════════════════╣
║ 06409   ║ coffe créma                      ║ 150        ║ 00011001 00001001 ║
║ 06178   ║ espresso                         ║ 80         ║ 00011000 00100010 ║
║ 63735   ║ milk for latte (big disk)        ║ ?          ║ 11111000 11110111 ║
║ 06182   ║ milk for cappuccino (small disk) ║ ?          ║ 00011000 00100110 ║
║ 06665   ║ hot chocolate                    ║ ?          ║ 00011010 00001001 ║
║ 07879   ║ service disk                     ║ 200        ║ 00011110 11000111 ║
╚═════════╩══════════════════════════════════╩════════════╩═══════════════════╝

The service disk is used for cleaning, it makes hot water at 60° C flow straight through without any brewing time.

Using a barcode printer, I tried to modify the Coffe Créma barcode to give 300 ml (the max amount from the patent). I did some really extensive testing, printing out and feeding the machine a handful of barcodes, and it would seem there are six bits in the barcode, not four, that control the amount. The data is available here at Google Docs. The 6-bit range in question is in the middle: last 3 bits of the first byte and first 3 bits of the second byte (big-endian). Because Google Docs don't support in-cell colours, there is also a more nicely coloured Excel file uploaded here at Google Drive.

So I identified two 6-bit sequences that resulted in 300 ml for Crema.
For the sake of interest, I took one of the sequences and put it into the respective place of the original Espresso barcode. And there it is, I got 300 ml of Espresso.

While this was sort of a success (I'm now able to produce barcodes with correct volumes for the drinks I'm interested in), I'm still completely lost as of exactly how this works. As you can see from the experiment table, the pattern is rather fuzzy, and there are entries that give same volume from different combination of bits. I'm also not sure I'm getting the same brewing parameters with the barcodes I made.

Please share your ideas on how to understand this further.

share|improve this question
1  
According to the second blog post you linked to, the last digit is a UPC-style check digit, and should be dropped before converting to binary (and recalculated for any modified codes). You just happened to be lucky that you two-bit change resulted in a number that passed the check. –  Ilmari Karonen Mar 20 at 18:35
1  
Note that the UPC check digit scheme is designed such that, for an even-length code that already ends with a correct check digit, repeating the calculation always gives zero. That is, for a correctly checksummed (even-length) code, (sum of even digits) + 3 * (sum of odd digits) ≡ 0 (mod 10). –  Ilmari Karonen Mar 20 at 18:40
    
@IlmariKaronen Yes, you are rigth, I overlooked this. When I removed the check digits all went rather well. Please see the edit. –  GSerg Mar 21 at 15:37
    
Looking at your table, i see you never flip the last bit of the first byte in your crema experiments. So this may or may not change anything. Also, the patent mentions different cartridge charges - with soak, without soak - which may affect the volume of water in the cup, as well as steam/no steam, which isn't mentioned in the patent. Last, the blog author mentions that american cartriges seem to have high first digits while europeans have zero; this might mean some bits have no effect on the apparatus, but serve as licensee/vendor identification. –  Guntram Blohm Mar 22 at 12:11

5 Answers 5

Consider the code that you were able to modify. The decimal representation of your modified code is 065375.

The checksum of 064095 =  3*0 + 6 + 3*4 + 0 + 3*9 + 5 = 50 (≡ 0 mod 10).
The checksum of 065375 =  3*0 + 6 + 3*5 + 3 + 3*7 + 5 = 50 (≡ 0 mod 10).

So it seems that this disk was accepted because the checksum matched, while your other disks weren't taken because of the wrong checksum.

Now, if i remove the checksum digit from the decimal numbers, and convert them to binary:

06409 = 0001 1001 0000 1001
06537 = 0001 1001 1000 1001

Unfortunately, that doesn't match anything from the patent volume table, even if i compare the larger volumes (170 / 230 to account for water that stays in the disc), or smaller volumes (130 / 190). - my two numbers have only one bit that's different, and each combination from the table needs more than one different bit. But, there's no guarantee for the volume table in the machine being identical to the one in the patent.

I'd try to take the above codes, flip one bit after another in each of them, calculate the decimal number, tack on the checksum digit, and print that to barcode, then check what happens:

$ ./bitflip 0001100100001001
1001100100001001 391771
0101100100001001 227933
0011100100001001 146012
0000100100001001 023139
0001000100001001 043618
0001110100001001 074339
0001101100001001 069212
0001100000001001 061537
0001100110001001 065375
0001100101001001 064736
0001100100101001 064415
0001100100011001 064255
0001100100000001 064019
0001100100001101 064132
0001100100001011 064118
0001100100001000 064088

If all these barcodes are accepted, they should produce different results which should give a hint at which bit has which meaning.

If you want to play with some other bit combinations, here's the source to my bitflip program (it's not the cleanest code, and it will produce strange results if you throw anything but binary digits at it, but it will do the job):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    int pos, pos2, binval, checksum;
    char oldbit;
    char buf[10];

    if (argc!=2 || strlen(argv[1]) != 16) {
            fprintf(stderr, "Need a 16 bit binary value\n");
            exit(1);
    }
    for (pos=0; pos<16; pos++) {
            oldbit=argv[1][pos];
            argv[1][pos]=(oldbit == '1' ? '0' : '1');
            binval=0;
            for (pos2=0; pos2<16; pos2++) {
                    binval=(binval<<1) | (argv[1][pos2]=='1');
            }
            sprintf(buf, "%05d", binval);
            checksum=
                     3*(buf[0]-'0')
                    +  (buf[1]-'0')
                    +3*(buf[2]-'0')
                    +  (buf[3]-'0')
                    +3*(buf[4]-'0');
            checksum=10-(checksum%10);
            if (checksum==10)
                    checksum=0;
            printf("%16s %5s%d\n", argv[1], buf, checksum);
            argv[1][pos]=oldbit;
    }
}
share|improve this answer
    
Thanks for your input. I've uploaded some experimental data. –  GSerg Mar 21 at 15:29
  • Costa Americano (220ml) 297615 (single T Disc)
  • Costa Cappuccino (215ml) = Costa Espresso for Cappuccino & Latte 022095 + Creamer (S) for Cappuccino 061827
  • Costa Caramel Latte (320ml) = Costa Espresso for Cappuccino & Latte 022095 + Creamer (L) for Caramel Latte 637350
  • Cadbury Hot Chocolate (265ml) = Cadbury Hot Chocolate 066655 + Creamer (S) for Cadbury 061827

Notes:

  1. Creamer for Capuccino and Creamer for Cadbury has the same barcode although different foil labels.
  2. Costa Cappuccino and Costa Caramel Latte use the same Costa Espresso for Cappuccino & Latte T Discs
share|improve this answer
    
Thanks, I will take into account the Americano and Costa Espresso. I already have the other barcode values listed though, under different names. –  GSerg Apr 6 at 18:04

From Google Images (Large)

  • (Creamer / Milk) for Chai Latte 674478
  • Gevalia Kaffe Espresso 849838 (Professional T-Disc apparently not compatible with home brewers)
  • Gevalia Kaffe Espresso 594912
  • Gevalia Kaffe Signature Blend 642262
  • Maxwell House Morning 648035 (Large 12floz serving 355ml?)
  • Starbucks Espresso Roast 596831
  • Nabob Breakfast Du Matin 683050
  • Corner Coffee House Peppermint Chocolate Syrup 676458
  • Tea Bar Peach Iced Tea 349130 (Is this unheated water?)
  • Tazo Awake Black Tea 699556
share|improve this answer
  • Twinings English Breakfast Tea (195ml) 032872 (single T Disc)
  • Milka Hot Chocolate (245ml) = Milka Chocolate 066655 + Creamer (S) for Milka, Marabou & Freia 061827
  • Suchard Hot Chocolate (195ml) 047852 (single T Disc)
  • Carte Noire Cappuccino (190ml) = Carte Noire Expresso Intense 061780 + Creamer (S) for Cappuccino 061827
  • Kenco Medium Roast (195ml) 297615 (single T Disc)
  • Carte Noire Petit Dejeuner Classic (215ml) 297615 (single T Disc)
  • CarteNoire Espresso Classic (60ml) 061780 (single T Disc)

Notes:

  1. Carte Noire Espresso Classic 60ml + Carte Noire Expresso Intense from Cappuccino 190ml share barcodes that may imply Creamer for Cappuccino = 130ml?
  2. Kenco Medium Roast 195ml + Carte Noire Petit Dejeuner Classic 215ml share same barcode even though 20ml difference?
share|improve this answer

I've got a lead!!

I've looked over a lot of the data, and I think that people are getting distracted by the decimal representations of the binaries. We need to just focus on the binaries. I first got that idea from a mysteriously precise comment on the chapman consulting post. Seems like someone with some inside knowledge, possibly.

GSerg, the OP, posted a great Google spreadsheet of experiments with the binaries.

My hypothesis is that there are bit ranges dedicated to certain functions. For instance, I've isolated the liquid volume to a particular three bits (8 settings). However, I think that the liquid volume changes based on a different bit-ranges.

I think there are modes, and each one has it's own temperature range.

Here is a copy of the OP's spreadsheet, with spacing on the binaries to isolate where the important volume bits are.

https://docs.google.com/spreadsheets/d/1Qpj4KC9xK5Dr7VY5HoNWr9azHKRl94jKABDwTKTbUfg/edit?usp=sharing

Granted, this isn't perfect - 011 coming after 100 in each range is irritating, but at least it's consistent. I think this is the first direct correlation of barcode to function that we have.

We are closer than ever to cracking this! With a bit more data, especially temperature data, I think I could figure it out.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.