|
本帖最后由 HuaShine2015 于 2016-5-26 20:58 编辑
前言:
免滚码破解,无需拆装,手机APP作为车门遥控钥匙。
屌丝车怎样简单粗暴的实现某V品牌汽车高大上B格,拎包入住步骤如下。
主题:
这是本人代步小破车遥控钥匙原来的样子
(表和我说射频破解MCU加RF模块模拟啥啥的,现在遥控器都滚码433M哦,还双向验证。撇开破解难度不谈,你要是让你老婆知道你折腾半夜就为破解滚码这破玩意,估计得罚洗尿布半年)
然后加上翅膀配上航弹
配齐主要机组人员
准备起飞
背景:
原理图概述
模块特性
使用的TI公司CC254X平台BLE蓝牙模块DX-BT05,内部封装的固件版本较简陋(此模块未过MFi认证的)。 MCU使用pro mini
系统特性
软件流程图
MCU端代码 - //2016-5-26 create by Shine.Hua
-
- #include <Enerlib.h>
- #include <EEPROM.h>
- #define HWRSTPIN 7
- #define LOCKPIN 4
- #define UNLOCKPIN 5
- #define DEFAULTPIN 6
- #define DETECTPIN 2
- #define MCULED 13
- struct CellObject {
- char mac0[13];
- char mac1[13];
- char mac2[13];
- char pin[7];
- };
- Energy energy;
- CellObject cob;
- String pin_type = "AT+TYPE0";
- String inputString = "";
- boolean stringComplete = false;
- boolean license = false;
- boolean sts = false;
- const unsigned long WAIT_TIME1 = 120000;
- const unsigned long WAIT_TIME2 = 25000;
- const unsigned long WAIT_TIME3 = 200000;
- unsigned long connStop = 0;
- unsigned long mcuSleep = 0;
- CellObject get_Conn() {
- CellObject getvaul;
- EEPROM.get(0, getvaul);
- return getvaul;
- }
- void set_Conn(CellObject setVar) {
- EEPROM.put(0, setVar);
- EEPROM.put(512, 1);
- }
- void clrEEPROM() {
- for (int i = 0 ; i < EEPROM.length() ; i++) {
- EEPROM.write(i, 0);
- }
- }
- void default_set() { //MCU烧录后EEPROM均是清空状态,所以此函数功能是保留至少要能保存设置一个可以连接的MAC,能让手机APP连接后再修改
- clrEEPROM();
- delay(1000);
- CellObject defaultVar = {
- "", //发现官方EEPROM库函数有bug,创建对象时第一个属性值读写不全。此处创建结构体类时,第一个属性留空
- "008012345678",
- "EA3146CE9FF7",
- "000000"
- };
- pin_type = "AT+TYPE0";
- set_Conn(defaultVar);
- root_bt();
- }
- void bt_hw_rst() { //蓝牙模块连接以后自动切换到透传模式,此时无法接收AT指令
- digitalWrite(HWRSTPIN, HIGH); //所以此处使用切换蓝牙HW_RST PIN状态来强制断开蓝牙连接恢复到AT指令模式
- delay(1500);
- digitalWrite(HWRSTPIN, LOW);
- delay(3500);
- wakeup_bt();
- sleep_bt();
- }
- void bt_sf_rst() {
- Serial.println("AT+RESET\r");
- delay(2500);
- }
- void sleep_bt() {
- Serial.println("AT+SLEEP\r");
- delay(1000);
- }
- void wakeup_bt() {
- for (int i = 0; i <= 12; i++) {
- Serial.print("WAKEUPBT");
- }
- Serial.println("\r");
- delay(1500);
- }
- void root_bt() { //设置蓝牙模块
- while (true) {
- digitalWrite(MCULED, !digitalRead(MCULED));
- if (digitalRead(DETECTPIN) == LOW) {
- delay(30);
- if (digitalRead(DETECTPIN) == LOW) {
- break;
- }
- }
- delay(250);
- }
- digitalWrite(MCULED, HIGH);
- wakeup_bt();
- //Serial.println("AT+NAMELIFAN320\r");
- //delay(600);
- Serial.print(pin_type); Serial.println("\r");
- delay(500);
- cob = get_Conn();
- Serial.print("AT+PIN"); Serial.print(cob.pin); Serial.println("\r");
- delay(800);
- Serial.println("AT+ROLE0\r");
- delay(500);
- Serial.println("AT+NOTI1\r");
- delay(500);
- Serial.println("AT+NOTP1\r");
- delay(500);
- Serial.println("AT+IMME0\r");
- delay(500);
- Serial.println("AT+PWRM0\r");
- delay(1000);
- bt_sf_rst();
- digitalWrite(MCULED, LOW);
- }
- void ctrl_login() { //控制MCU是否可以休眠
- if (digitalRead(DETECTPIN) == LOW) {
- delay(30);
- if (digitalRead(DETECTPIN) == LOW) {
- delay(30);
- if (digitalRead(DETECTPIN) == LOW) {
- sts = false;
- license = false;
- mcu_sleep();
- }
- }
- }
- }
- void ctrl_timeout() { //连接超时控制
- unsigned long currentMillis = millis();
- if (digitalRead(DETECTPIN) == HIGH) {
- delay(30);
- if (digitalRead(DETECTPIN) == HIGH) {
- delay(30);
- if (digitalRead(DETECTPIN) == HIGH) {
- if ( (license == false) && (currentMillis - connStop >= WAIT_TIME2)) {
- connStop = currentMillis;
- Serial.println("timeout1");
- bt_hw_rst();
- } else if (license == true && (currentMillis - connStop >= WAIT_TIME1) && stringComplete != true && (!Serial.available())) {
- connStop = currentMillis;
- Serial.println("timeout2");
- bt_hw_rst();
- }
- }
- }
- }
- }
- void mcu_sleep() { //MCU休眠代码
- unsigned long currentMillis = millis();
- if (currentMillis - mcuSleep >= WAIT_TIME3) {
- mcuSleep = currentMillis;
- Serial.println("mcuslp");
- wakeup_bt();
- sleep_bt();
- energy.PowerDown();
- }
- }
- void base_case() { //业务主体代码
- if (stringComplete) {
- if (digitalRead(DETECTPIN) == HIGH) {
- if (inputString.endsWith("close#") && license == true) {
- connStop = millis(); //
- mcuSleep = millis(); //
- digitalWrite(LOCKPIN, HIGH);
- delay(1100);
- digitalWrite(LOCKPIN, LOW);
- Serial.println("off");
- } else if (inputString.endsWith("open#") && license == true) {
- connStop = millis(); //
- mcuSleep = millis(); //
- digitalWrite(UNLOCKPIN, HIGH);
- delay(1100);
- digitalWrite(UNLOCKPIN, LOW);
- Serial.println("on");
- } else if (inputString.endsWith(";") && license == true) {
- connStop = millis(); //
- mcuSleep = millis(); //
- cob = get_Conn();
- String temp = inputString.substring((inputString.indexOf(';') - 6), inputString.indexOf(';'));
- for (int i = 0; i < temp.length(); i++) {
- cob.pin[i] = temp[i];
- }
- Serial.println(cob.pin);
- set_Conn(cob);
- root_bt();
- } else if (inputString.endsWith("admin#") && license == true) {
- connStop = millis(); //
- mcuSleep = millis(); //
- Serial.print("{"user1":"");Serial.print(cob.mac1);Serial.print("","user2":""); //返回JSON格式
- Serial.print(cob.mac2);Serial.print("","PIN":"");Serial.print(cob.pin);Serial.print(""}");
- } else if (inputString.endsWith("}") && license == true) {
- connStop = millis(); //
- mcuSleep = millis(); //
- cob = get_Conn();
- String temp = inputString.substring((inputString.indexOf('}') - 12), inputString.indexOf('}'));
- for (int i = 0; i < temp.length(); i++) {
- cob.mac1[i] = temp[i];
- }
- Serial.println(cob.mac1);
- set_Conn(cob);
-
- } else if (inputString.endsWith("]") && license == true) {
- connStop = millis(); //
- mcuSleep = millis(); //
- cob = get_Conn();
- String temp = inputString.substring((inputString.indexOf(']') - 12), inputString.indexOf(']'));
- for (int i = 0; i < temp.length(); i++) {
- cob.mac2[i] = temp[i];
- }
- Serial.println(cob.mac2);
- set_Conn(cob);
-
- } else if (inputString.endsWith("skoff#") && license == true) {
- connStop = millis(); //
- mcuSleep = millis(); //
- pin_type = "AT+TYPE0";
- Serial.println(pin_type);
- root_bt();
- } else if (inputString.endsWith("skon#") && license == true) {
- connStop = millis(); //
- mcuSleep = millis(); //
- pin_type = "AT+TYPE3";
- Serial.println(pin_type);
- root_bt();
- } else if (license == false) {
- Serial.println("ghost");
- }
- }
- inputString = "";
- stringComplete = false;
- }
- delay(50);
- }
- void wakeISR() { //唤醒后执行代码
- if (energy.WasSleeping()) {
- digitalWrite(MCULED, HIGH);
- Serial.println("mcuwk");
- connStop = millis();
- mcuSleep = millis();
- delay(1000);
- digitalWrite(MCULED, LOW);
- } else {
- }
- }
- void setup() { //MCU初始化
-
- digitalWrite(HWRSTPIN, LOW);
- digitalWrite(DEFAULTPIN, HIGH);
- digitalWrite(LOCKPIN, LOW);
- digitalWrite(UNLOCKPIN, LOW);
-
- pinMode(HWRSTPIN, OUTPUT);
- pinMode(DEFAULTPIN, OUTPUT);
- pinMode(DETECTPIN, INPUT_PULLUP);
- pinMode(LOCKPIN, OUTPUT);
- pinMode(UNLOCKPIN, OUTPUT);
- pinMode(MCULED, OUTPUT);
- digitalWrite(HWRSTPIN, LOW);
- digitalWrite(DEFAULTPIN, HIGH);
- digitalWrite(LOCKPIN, LOW);
- digitalWrite(UNLOCKPIN, LOW);
- digitalWrite(MCULED, LOW);
- Serial.begin(9600);
- inputString.reserve(200);
- if (digitalRead(DEFAULTPIN) == LOW) {
- delay(20);
- if (digitalRead(DEFAULTPIN) == LOW) {
- default_set();
- }
- }
- if (EEPROM.read(512) != 1) {
- default_set();
- }
- attachInterrupt(0, wakeISR, RISING);
- }
- void loop() { //主循环代码
- base_case();
- ctrl_login();
- ctrl_timeout();
- delay(500);
- }
- void serialEvent() { //串口事件响应代码
- cob = get_Conn();
- char str[13];
- int idx = 0;
- boolean mc1 = false;
- boolean mc2 = false;
- boolean back = true;
- while (Serial.available()) {
- char inChar = (char)Serial.read();
- inputString += inChar;
- if (inputString.indexOf('x') != -1 && idx < 13 && sts == false) {
- str[idx++] = inChar;
- }
- if (idx >= 13 && sts == false) {
- mc1 = true;
- mc2 = true;
- /*for (int i = 0; i < 12; i++) {
- Serial.print(cob.mac1[i]);
- Serial.print("-");
- }
- Serial.println();
- for (int i = 0; i < 12; i++) {
- Serial.print(cob.mac2[i]);
- Serial.print("+");
- }
- Serial.println();
- for (int i = 0; i < 6; i++) {
- Serial.print(cob.pin[i]);
- Serial.print("*");
- }*/
- for (int i = 0; i < 12; i++) {
- if (cob.mac1[i] != str[i + 1]) {
- mc1 = false;
- break;
- }
- }
- for (int i = 0; i < 12; i++) {
- if (cob.mac2[i] != str[i + 1]) {
- mc2 = false;
- break;
- }
- }
- if (mc1 == true || mc2 == true) {
- license = true;
- sts = true;
- } else if((mc1 == true || mc2 == true)&&(back == true)) {
- Serial.print("login:");
- for (int i = 0; i < 12; i++) {
- Serial.print(str[i + 1]);
- }
- Serial.println();
- back = false;
- }
- }
- if ((inChar == '#') || (inChar == '}')
- || (inChar == ']') || (inChar == ';')) {
- stringComplete = true;
- }
- }
- }
复制代码
MCU端封装的软件接口明细
手机APP端UI
使用BLE GATT协议通讯,代码见所附下载地址,不详述
附言:
1.如需实践,切记关机后充电,也就是断开输出负载
其实供电部分可以用MOS管加Attiny控制来实现和手机一样的开机充电
2.此蓝牙模块有几个bug
--和IOS系统可以正常连接和GATT协议通讯,但应该是未过MFi认证的原因,底层固件无权限取得IOS端设备MAC。
此时会用一种随机算法虚拟一个MAC地址抛给MCU,这比较讨厌 。
--此模块固件如设置上电后等待MCU指令模式,MCU给休眠指令后,无法正常休眠。只适合上电自运行模式
3.如不考虑能耗问题,可以使用此蓝牙的主模式,搜索附近指定MAC的RSSI值来判断是否车主接近和离开。
这样可以实现免操作自动开关门,代码实现不难,有兴趣的可以尝试一下。
本文所有源码下载路径
http://pan.baidu.com/s/1eSJNoHk
厂商参考资料下载路径
http://pan.baidu.com/s/1eSJNoHk |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|