小米手环分析
本文地址:http://txm.tongxinmao.com/Article/Detail/id/205
小米手环分析
http://www.blogjava.net/baicker/archive/2015/09/05/427125.html


小米手环主要部件:蓝牙模块Dialog DA14580,陀螺仪ADXL362,DC-DC选用的TI的TPS62736
认证很简单,只需要在FF04的UUID中写入20字节的值并校验通过,就可以对手环进行读写指令控制。
其实有个更简单的,只要给Immediate Alert这个属性发送0x01或者0x02即可启动“女性娱乐模式”,不需要任何认证:
(这个属性本来是用来可穿戴设备的找回功能的)
如果还需要闪光,变色之类的操作,就需要填对FF04中的信息,然后向手环发送指令:
ID-ID-ID-ID-01-11-AF-4B-00-30-30-39-00-00-00-00-00-00-00-71
前四字节:ID(小米登录后有ID号) 
01:性别
11:年龄
AF:身高(cm)
4B:体重(kg) 
00:忘了,可能是体重的高位字节(咳~~嗯小米考虑得很周全)
303039:昵称(009)
71:校验
校验是怎么来的呢?
前19字节的CRC8^MAC最后一位(小米的MAC一般都是880F10开头的)
网上找了段C代码,初始化参数有点不一样,FF->00,9C->8C
#define CRC_POLYNOM 0x8c
#define CRC_PRESET 0x00
#include <stdio.h>
#include <stdlib.h>     /* strtol */
#define CRC_POLYNOM 0x8c
#define CRC_PRESET 0x00
int main(int argc, char* argv[]) {
    if(argc!=21 && argc!=2){
        printf("\n\tMiband userinfo checksum by 009\n");
        printf("\t  Usage: %s [arrayOfByte] <lastBleAddr>\n", argv[0]);
        printf("\t\t%s 0x88\n", argv[0]);
        printf("\t\t%s 0xA3 0xF0 0x1D 0x28 0x01 0x20 0xAA 0x3C 0x01 0x30 0x30 0x39 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88\n\n", argv[0]);
        return 0;
    }
    unsigned char FRAME[] = {0xA3, 0xF0, 0x1D, 0x28, 0x01, 0x20, 0xAA, 0x3C, 0x01, 0x30, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};   
    unsigned char lastAddr = strtol(argv[20],NULL,0);
    unsigned int crc = CRC_PRESET;
    if(argc==21){
        for(int i = 0; i < 19; i++)FRAME[i]=strtol(argv[i+1],NULL,0);
    }
    for(int i = 0; i < sizeof(FRAME); i++) {
        crc ^= FRAME[i];
        for(int j = 0; j < 8; j++) {
            if(crc & 0x01) {
                crc = (crc >> 1) ^ CRC_POLYNOM;
            } else {
                crc = (crc >> 1);
            }
        }
    }
    printf("CRC8=%02X\n", crc);
    for(i = 0; i < 19; i++)printf("%02X-", FRAME[i]);
    printf("%02X\n", crc^lastAddr);    //0x3A mac地址最后一字节
    return 0;
}
下面是各种UUID:
Characteristic  | Handle  | UUID  | Des  | ||
UUID_SERVICE_MILI_SERVICE  | FEE0  | 服务  | |||
UUID_CHARACTERISTIC_DEVICE_INFO  | FF01  | R  | 88-7C-XX-XX-00-00-02-B5-00-06-00-02-30-09-00-01  | 设备信息  | |
UUID_CHARACTERISTIC_DEVICE_NAME  | FF02  | RW  | 00-60-09-4D-49  | 设备名称  | |
UUID_CHARACTERISTIC_NOTIFICATION  | FF03  | Notify,R  | 15  | ||
0x2902  | R  | 01-00  | notify  | ||
UUID_CHARACTERISTIC_USER_INFO  | 19  | FF04  | RW  | XX-XX-1D-28-01-11-AF-4B-01-30-30-39-00-00-00-00-00-00-00-71  | |
UUID_CHARACTERISTIC_CONTROL_POINT  | 1B  | FF05  | W  | 控制指令  | |
UUID_CHARACTERISTIC_REALTIME_STEPS  | FF06  | Notify,R  | B9-14-00-00  | 步数  | |
0x2902  | R  | 01-00  | realtimedata  | ||
UUID_CHARACTERISTIC_ACTIVITY_DATA  | FF07  | Notify,R  | 01-0F-05-11-10-06-04-00-00-00-00  | ||
0x2902  | R  | 01-00  | Data  | ||
UUID_CHARACTERISTIC_FIRMWARE_DATA  | FF08  | W  | 升级数据  | ||
UUID_CHARACTERISTIC_LE_PARAMS  | FF09  | Notify,RW  | CC-01-F4-01-00-00-F4-01-F4-01-08-08  | ||
0x2902  | R  | 6C-65-70-61-72-61-6D  | leparam  | ||
UUID_CHARACTERISTIC_DATE_TIME  | 28  | FF0A  | RW  | 0F-05-11-10-05-33-0F-05-11-10-06-05  | |
UUID_CHARACTERISTIC_STATISTICS  | FF0B  | RW  | 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  | ||
UUID_CHARACTERISTIC_BATTERY  | FF0C  | Notify,R  | 1C-0F-04-0D-0A-32-33-05-00-00  | 电池信息  | |
0x2902  | R  | 01-00  | Battery  | ||
UUID_CHARACTERISTIC_TEST  | 2E  | FF0D  | RW  | B7-1D  | |
FF0E  | Notify,RW  | ||||
0x2902  | R  | 01-00  | fulldata  | ||
PAIR,写入02解除  | 33  | FF0F  | RW  | FF-FF  | |
补充  | |||||
0x0014  | FF02  | 01 广播 00 不广播  | 
电池信息:1C-0F-04-0D-0A-32-33-05-00-00
没啥大用,第一个字节电量百分比,之后上次充电的年月日时间等。
FF05是发送控制指令用的,常用的如下:
UUID  | 作用  | 值  | 
FF05  | updateFirmware  | 07XXXXXX ...  | 
SetGoal  | 0500LLHH  | |
SetColor  | 0ERRGGBB01  | |
StartVibrate  | 0801  | |
StopVibrate  | 0D  | |
Vibrate  | 0802  | |
Vibrate + LED  | 0800  | |
FactoryReset  | 09  | |
Reboot  | 0C  | |
Sync  | 0B  | |
左右手  | 0FXX  | |
打开实时步数提示  | 0301  | |
关闭实时步数提示  | 0300  | 
例如:成功写入了如下FF04之后,
写入完成后,向FF05写入0E06000001就设置了手环发红光。。。
点击读FF06就会获得当前步数(好像这个值不需要写FF04也可以,懒得试了)
另:各个固件可以随便刷,不用考虑能不能降版本的问题。手机APP只是手机端做了限制。
如果哪位大侠分析出了固件升级时候校验是怎么校验的,望赐教,ARM逆向实在搞不定。
不会写手机端APP,否则可以搞一些比较好(wei)玩(suo)的事情。
以上分析不一定完全正确,有错误的地方欢迎指正。
上一篇:Printer gadget driver
下一篇:NanoPi M2 首次启动信息