mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-20 23:04:30 +01:00
Added ATC BLE OEPL Sending
This commit is contained in:
@@ -6,5 +6,6 @@ uint8_t gicToOEPLtype(uint8_t gicType);
|
||||
bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice);
|
||||
bool BLE_is_image_pending(uint8_t address[8]);
|
||||
uint32_t compress_image(uint8_t address[8], uint8_t* buffer, uint32_t max_len);
|
||||
uint32_t get_ATC_BLE_OEPL_image(uint8_t address[8], uint8_t* buffer, uint32_t max_len, uint8_t* dataType, uint8_t* dataTypeArgument, uint16_t* nextCheckIn);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -64,6 +64,16 @@ uint8_t gicToOEPLtype(uint8_t gicType) {
|
||||
}
|
||||
}
|
||||
|
||||
struct BleAdvDataStruct {
|
||||
uint16_t manu_id; // 0x1337 for us
|
||||
uint8_t version;
|
||||
uint16_t hw_type;
|
||||
uint16_t fw_version;
|
||||
uint16_t capabilities;
|
||||
uint16_t battery_mv;
|
||||
uint8_t counter;
|
||||
} __packed;
|
||||
|
||||
bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice) {
|
||||
Serial.print("BLE Advertised Device found: ");
|
||||
Serial.println(advertisedDevice.toString().c_str());
|
||||
@@ -103,10 +113,46 @@ bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice) {
|
||||
theAdvData.src[7] = manuData[6];
|
||||
theAdvData.adr.batteryMv = manuData[3] * 100;
|
||||
theAdvData.adr.lastPacketRSSI = advertisedDevice.getRSSI();
|
||||
theAdvData.adr.lastPacketLQI = advertisedDevice.getRSSI();
|
||||
theAdvData.adr.hwType = gicToOEPLtype(manuData[2]);
|
||||
theAdvData.adr.tagSoftwareVersion = manuData[4] << 8 | manuData[5];
|
||||
theAdvData.adr.capabilities = 0x00;
|
||||
|
||||
processDataReq(&theAdvData, true);
|
||||
return true;
|
||||
} else if (manuDatalen >= sizeof(BleAdvDataStruct) && manuData[0] == 0x37 && manuData[1] == 0x13) { // Lets check for a Gicisky E-Paper display
|
||||
Serial.printf("ATC BLE OEPL Detected\r\n");
|
||||
struct espAvailDataReq theAdvData;
|
||||
struct BleAdvDataStruct inAdvData;
|
||||
|
||||
memset((uint8_t*)&theAdvData, 0x00, sizeof(espAvailDataReq));
|
||||
memcpy(&inAdvData, manuData, sizeof(BleAdvDataStruct));
|
||||
/*Serial.printf("manu_id %04X\r\n", inAdvData.manu_id);
|
||||
Serial.printf("version %04X\r\n", inAdvData.version);
|
||||
Serial.printf("hw_type %04X\r\n", inAdvData.hw_type);
|
||||
Serial.printf("fw_version %04X\r\n", inAdvData.fw_version);
|
||||
Serial.printf("capabilities %04X\r\n", inAdvData.capabilities);
|
||||
Serial.printf("battery_mv %u\r\n", inAdvData.battery_mv);
|
||||
Serial.printf("counter %u\r\n", inAdvData.counter);*/
|
||||
if (inAdvData.version != 1) {
|
||||
printf("Version currently not supported!\r\n");
|
||||
return false;
|
||||
}
|
||||
uint8_t macReversed[6];
|
||||
memcpy(&macReversed, (uint8_t*)advertisedDevice.getAddress().getNative(), 6);
|
||||
theAdvData.src[0] = macReversed[5];
|
||||
theAdvData.src[1] = macReversed[4];
|
||||
theAdvData.src[2] = macReversed[3];
|
||||
theAdvData.src[3] = macReversed[2];
|
||||
theAdvData.src[4] = macReversed[1];
|
||||
theAdvData.src[5] = macReversed[0];
|
||||
theAdvData.src[6] = manuData[0]; // We use this do find out what type of display we got for compression^^
|
||||
theAdvData.src[7] = manuData[1];
|
||||
theAdvData.adr.batteryMv = inAdvData.battery_mv;
|
||||
theAdvData.adr.lastPacketRSSI = advertisedDevice.getRSSI();
|
||||
theAdvData.adr.hwType = inAdvData.hw_type & 0xff;
|
||||
theAdvData.adr.tagSoftwareVersion = inAdvData.fw_version;
|
||||
theAdvData.adr.capabilities = inAdvData.capabilities & 0xff;
|
||||
processDataReq(&theAdvData, true);
|
||||
return true;
|
||||
}
|
||||
@@ -133,7 +179,6 @@ bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice) {
|
||||
theAdvData.adr.hwType = ATC_MI_THERMOMETER;
|
||||
theAdvData.adr.tagSoftwareVersion = 0x00;
|
||||
theAdvData.adr.capabilities = 0x00;
|
||||
|
||||
processDataReq(&theAdvData, true);
|
||||
Serial.printf("We got an ATC_MiThermometer via BLE\r\n");
|
||||
return true;
|
||||
@@ -150,6 +195,14 @@ bool BLE_is_image_pending(uint8_t address[8]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (int16_t c = 0; c < tagDB.size(); c++) {
|
||||
tagRecord* taginfo = tagDB.at(c);
|
||||
if (taginfo->pendingCount > 0 && taginfo->version == 0 && (taginfo->mac[7] == 0x13) && (taginfo->mac[6] == 0x37)) {
|
||||
memcpy(address, taginfo->mac, 8);
|
||||
Serial.printf("ATC BLE OEPL data Waiting\r\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -374,4 +427,37 @@ uint32_t compress_image(uint8_t address[8], uint8_t* buffer, uint32_t max_len) {
|
||||
return len_compressed;
|
||||
}
|
||||
|
||||
uint32_t get_ATC_BLE_OEPL_image(uint8_t address[8], uint8_t* buffer, uint32_t max_len, uint8_t* dataType, uint8_t* dataTypeArgument, uint16_t* nextCheckIn) {
|
||||
uint32_t t = millis();
|
||||
PendingItem* queueItem = getQueueItem(address, 0);
|
||||
if (queueItem == nullptr) {
|
||||
prepareCancelPending(address);
|
||||
Serial.printf("blockrequest: couldn't find taginfo %02X%02X%02X%02X%02X%02X%02X%02X\r\n", address[7], address[6], address[5], address[4], address[3], address[2], address[1], address[0]);
|
||||
return 0;
|
||||
}
|
||||
if (queueItem->data == nullptr) {
|
||||
fs::File file = contentFS->open(queueItem->filename);
|
||||
if (!file) {
|
||||
Serial.print("No current file. " + String(queueItem->filename) + " Canceling request\r\n");
|
||||
prepareCancelPending(address);
|
||||
return 0;
|
||||
}
|
||||
queueItem->data = getDataForFile(file);
|
||||
Serial.println("Reading file " + String(queueItem->filename) + " in " + String(millis() - t) + "ms");
|
||||
file.close();
|
||||
}
|
||||
if (queueItem->len > max_len) {
|
||||
Serial.print("The upload is too big better cencel it\r\n");
|
||||
prepareCancelPending(address);
|
||||
return 0;
|
||||
}
|
||||
*dataType = queueItem->pendingdata.availdatainfo.dataType;
|
||||
*dataTypeArgument = queueItem->pendingdata.availdatainfo.dataTypeArgument;
|
||||
*nextCheckIn = queueItem->pendingdata.availdatainfo.nextCheckIn;
|
||||
uint32_t len_compressed = queueItem->len;
|
||||
memcpy(buffer, queueItem->data, queueItem->len);
|
||||
Serial.print("Data is prepared Len: " + String(queueItem->len) + "\r\n");
|
||||
return queueItem->len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef HAS_BLE_WRITER
|
||||
#include <Arduino.h>
|
||||
#include <MD5Builder.h>
|
||||
|
||||
#include "BLEDevice.h"
|
||||
#include "ble_filter.h"
|
||||
@@ -7,12 +8,13 @@
|
||||
|
||||
#define INTERVAL_BLE_SCANNING_SECONDS 60
|
||||
#define INTERVAL_HANDLE_PENDING_SECONDS 10
|
||||
#define BUFFER_MAX_SIZE_COMPRESSING 100000
|
||||
#define BUFFER_MAX_SIZE_COMPRESSING 135000
|
||||
|
||||
#define BLE_MAIN_STATE_IDLE 0
|
||||
#define BLE_MAIN_STATE_PREPARE 1
|
||||
#define BLE_MAIN_STATE_CONNECT 2
|
||||
#define BLE_MAIN_STATE_UPLOAD 3
|
||||
#define BLE_MAIN_STATE_ATC_BLE_OEPL_UPLOAD 4
|
||||
|
||||
int ble_main_state = BLE_MAIN_STATE_IDLE;
|
||||
uint32_t last_ble_scan = 0;
|
||||
@@ -23,9 +25,25 @@ uint32_t last_ble_scan = 0;
|
||||
#define BLE_UPLOAD_STATE_UPLOAD 5
|
||||
int BLE_upload_state = BLE_UPLOAD_STATE_INIT;
|
||||
|
||||
#define BLE_CMD_ACK_CMD 99
|
||||
#define BLE_CMD_AVAILDATA 100
|
||||
#define BLE_CMD_BLK_DATA 101
|
||||
#define BLE_CMD_ERR_BLKPRT 196
|
||||
#define BLE_CMD_ACK_BLKPRT 197
|
||||
#define BLE_CMD_REQ 198
|
||||
#define BLE_CMD_ACK 199
|
||||
#define BLE_CMD_ACK_IS_SHOWN 200
|
||||
#define BLE_CMD_ACK_FW_UPDATED 201
|
||||
|
||||
struct AvailDataInfo BLEavaildatainfo = {0};
|
||||
struct blockRequest BLEblkRequst = {0};
|
||||
|
||||
bool BLE_connected = false;
|
||||
bool BLE_new_notify = false;
|
||||
|
||||
static BLEUUID ATC_BLE_OEPL_ServiceUUID((uint16_t)0x1337);
|
||||
static BLEUUID ATC_BLE_OEPL_CtrlUUID((uint16_t)0x1337);
|
||||
|
||||
static BLEUUID gicServiceUUID((uint16_t)0xfef0);
|
||||
static BLEUUID gicCtrlUUID((uint16_t)0xfef1);
|
||||
static BLEUUID gicImgUUID((uint16_t)0xfef2);
|
||||
@@ -33,20 +51,21 @@ static BLEUUID gicImgUUID((uint16_t)0xfef2);
|
||||
BLERemoteCharacteristic* ctrlChar;
|
||||
BLERemoteCharacteristic* imgChar;
|
||||
BLEAdvertisedDevice* myDevice;
|
||||
|
||||
BLEClient* pClient;
|
||||
|
||||
uint8_t BLE_notify_buffer[255] = {0};
|
||||
uint8_t BLE_notify_buffer[256] = {0};
|
||||
|
||||
uint32_t curr_part = 0;
|
||||
uint8_t BLE_buff[255];
|
||||
uint32_t BLE_err_counter = 0;
|
||||
uint32_t BLE_curr_part = 0;
|
||||
uint32_t BLE_max_block_parts = 0;
|
||||
uint8_t BLE_mini_buff[256];
|
||||
|
||||
uint32_t BLE_last_notify = 0;
|
||||
uint32_t BLE_last_pending_check = 0;
|
||||
uint8_t BLE_curr_address[8] = {0};
|
||||
|
||||
uint32_t compressed_len = 0;
|
||||
uint8_t* buffer;
|
||||
uint32_t BLE_compressed_len = 0;
|
||||
uint8_t* BLE_image_buffer;
|
||||
|
||||
static void notifyCallback(
|
||||
BLERemoteCharacteristic* pBLERemoteCharacteristic,
|
||||
@@ -81,7 +100,13 @@ class MyClientCallback : public BLEClientCallbacks {
|
||||
}
|
||||
};
|
||||
|
||||
bool BLE_connect(uint8_t addr[8]) {
|
||||
enum BLE_CONNECTION_TYPE {
|
||||
BLE_TYPE_GICISKY = 0,
|
||||
BLE_TYPE_ATC_BLE_OEPL
|
||||
};
|
||||
|
||||
bool BLE_connect(uint8_t addr[8], BLE_CONNECTION_TYPE conn_type) {
|
||||
BLE_err_counter = 0;
|
||||
uint8_t temp_Address[] = {addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]};
|
||||
Serial.printf("BLE Connecting to: %02X:%02X:%02X:%02X:%02X:%02X\r\n", addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
|
||||
pClient = BLEDevice::createClient();
|
||||
@@ -92,25 +117,27 @@ bool BLE_connect(uint8_t addr[8]) {
|
||||
return false;
|
||||
}
|
||||
uint32_t timeStart = millis();
|
||||
while (millis() - timeStart <= 5000) {// We wait for a few seconds as otherwise the connection might not be ready!
|
||||
while (millis() - timeStart <= 5000) { // We wait for a few seconds as otherwise the connection might not be ready!
|
||||
delay(100);
|
||||
}
|
||||
if (!BLE_connected)
|
||||
return false;
|
||||
Serial.printf("BLE starting to get service\r\n");
|
||||
BLERemoteService* pRemoteService = pClient->getService(gicServiceUUID);
|
||||
BLERemoteService* pRemoteService = pClient->getService((conn_type == BLE_TYPE_GICISKY) ? gicServiceUUID : ATC_BLE_OEPL_ServiceUUID);
|
||||
if (pRemoteService == nullptr) {
|
||||
Serial.printf("BLE Service failed\r\n");
|
||||
pClient->disconnect();
|
||||
return false;
|
||||
}
|
||||
imgChar = pRemoteService->getCharacteristic(gicImgUUID);
|
||||
if (imgChar == nullptr) {
|
||||
Serial.printf("BLE IMG Char failed\r\n");
|
||||
pClient->disconnect();
|
||||
return false;
|
||||
if (conn_type == BLE_TYPE_GICISKY) {
|
||||
imgChar = pRemoteService->getCharacteristic(gicImgUUID);
|
||||
if (imgChar == nullptr) {
|
||||
Serial.printf("BLE IMG Char failed\r\n");
|
||||
pClient->disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ctrlChar = pRemoteService->getCharacteristic(gicCtrlUUID);
|
||||
ctrlChar = pRemoteService->getCharacteristic((conn_type == BLE_TYPE_GICISKY) ? gicCtrlUUID : ATC_BLE_OEPL_CtrlUUID);
|
||||
if (ctrlChar == nullptr) {
|
||||
Serial.printf("BLE ctrl Char failed\r\n");
|
||||
pClient->disconnect();
|
||||
@@ -147,6 +174,49 @@ void BLE_startScan(uint32_t timeout) {
|
||||
pBLEScan->start(timeout, false);
|
||||
}
|
||||
|
||||
#define BLOCK_DATA_SIZE_BLE 4096
|
||||
#define BLOCK_PART_DATA_SIZE_BLE 230
|
||||
uint8_t tempBlockBuffer[BLOCK_DATA_SIZE_BLE + 4];
|
||||
uint8_t tempPacketBuffer[2 + 3 + BLOCK_PART_DATA_SIZE_BLE];
|
||||
void ATC_BLE_OEPL_PrepareBlk(uint8_t indexBlockId) {
|
||||
if (BLE_image_buffer == nullptr) {
|
||||
return;
|
||||
}
|
||||
uint32_t bufferPosition = (BLOCK_DATA_SIZE_BLE * indexBlockId);
|
||||
uint32_t lenNow = BLOCK_DATA_SIZE_BLE;
|
||||
uint16_t crcCalc = 0;
|
||||
if ((BLE_compressed_len - bufferPosition) < BLOCK_DATA_SIZE_BLE)
|
||||
lenNow = (BLE_compressed_len - bufferPosition);
|
||||
tempBlockBuffer[0] = lenNow & 0xff;
|
||||
tempBlockBuffer[1] = (lenNow >> 8) & 0xff;
|
||||
for (uint16_t c = 0; c < lenNow; c++) {
|
||||
tempBlockBuffer[4 + c] = BLE_image_buffer[c + bufferPosition];
|
||||
crcCalc += tempBlockBuffer[4 + c];
|
||||
}
|
||||
tempBlockBuffer[2] = crcCalc & 0xff;
|
||||
tempBlockBuffer[3] = (crcCalc >> 8) & 0xff;
|
||||
BLE_max_block_parts = (4 + lenNow) / BLOCK_PART_DATA_SIZE_BLE;
|
||||
if ((4 + lenNow) % BLOCK_PART_DATA_SIZE_BLE)
|
||||
BLE_max_block_parts++;
|
||||
Serial.println("Preparing block: " + String(indexBlockId) + " BuffPos: " + String(bufferPosition) + " LenNow: " + String(lenNow) + " MaxBLEparts: " + String(BLE_max_block_parts));
|
||||
BLE_curr_part = 0;
|
||||
}
|
||||
|
||||
void ATC_BLE_OEPL_SendPart(uint8_t indexBlockId, uint8_t indexPkt) {
|
||||
uint8_t crcCalc = indexBlockId + indexPkt;
|
||||
for (uint16_t c = 0; c < BLOCK_PART_DATA_SIZE_BLE; c++) {
|
||||
tempPacketBuffer[5 + c] = tempBlockBuffer[c + (BLOCK_PART_DATA_SIZE_BLE * indexPkt)];
|
||||
crcCalc += tempPacketBuffer[5 + c];
|
||||
}
|
||||
tempPacketBuffer[0] = 0x00;
|
||||
tempPacketBuffer[1] = 0x65;
|
||||
tempPacketBuffer[2] = crcCalc;
|
||||
tempPacketBuffer[3] = indexBlockId;
|
||||
tempPacketBuffer[4] = indexPkt;
|
||||
Serial.println("BLE Sending packet Len " + String(sizeof(tempPacketBuffer)));
|
||||
ctrlChar->writeValue(tempPacketBuffer, sizeof(tempPacketBuffer), true);
|
||||
}
|
||||
|
||||
void BLETask(void* parameter) {
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
Serial.println("BLE task started");
|
||||
@@ -162,25 +232,79 @@ void BLETask(void* parameter) {
|
||||
}
|
||||
if (millis() - BLE_last_pending_check >= (INTERVAL_HANDLE_PENDING_SECONDS * 1000)) {
|
||||
if (BLE_is_image_pending(BLE_curr_address)) {
|
||||
delay(4000); // We better wait here, since the pending image needs to be created first
|
||||
Serial.println("BLE Image is pending");
|
||||
// Here we create the compressed buffer
|
||||
buffer = (uint8_t*)malloc(BUFFER_MAX_SIZE_COMPRESSING);
|
||||
if (buffer == nullptr) {
|
||||
Serial.println("BLE Could not create buffer!");
|
||||
compressed_len = 0;
|
||||
} else {
|
||||
compressed_len = compress_image(BLE_curr_address, buffer, BUFFER_MAX_SIZE_COMPRESSING);
|
||||
Serial.printf("BLE Compressed Length: %i\r\n", compressed_len);
|
||||
// then we connect to BLE to send the compressed data
|
||||
if (compressed_len && BLE_connect(BLE_curr_address)) {
|
||||
curr_part = 0;
|
||||
memset(BLE_notify_buffer, 0x00, sizeof(BLE_notify_buffer));
|
||||
BLE_upload_state = BLE_UPLOAD_STATE_INIT;
|
||||
ble_main_state = BLE_MAIN_STATE_UPLOAD;
|
||||
BLE_new_notify = true; // trigger the upload here
|
||||
Serial.println("BLE Image is pending but we wait a bit");
|
||||
delay(5000); // We better wait here, since the pending image needs to be created first
|
||||
if (BLE_curr_address[7] == 0x13 && BLE_curr_address[6] == 0x37) { // This is an ATC BLE OEPL display
|
||||
// Here we create the compressed buffer
|
||||
BLE_image_buffer = (uint8_t*)malloc(BUFFER_MAX_SIZE_COMPRESSING);
|
||||
if (BLE_image_buffer == nullptr) {
|
||||
Serial.println("BLE Could not create buffer!");
|
||||
BLE_compressed_len = 0;
|
||||
} else {
|
||||
free(buffer);
|
||||
uint8_t dataType = 0x00;
|
||||
uint8_t dataTypeArgument = 0x00;
|
||||
uint16_t nextCheckin = 0x00;
|
||||
BLE_compressed_len = get_ATC_BLE_OEPL_image(BLE_curr_address, BLE_image_buffer, BUFFER_MAX_SIZE_COMPRESSING, &dataType, &dataTypeArgument, &nextCheckin);
|
||||
Serial.printf("BLE data Length: %i\r\n", BLE_compressed_len);
|
||||
// then we connect to BLE to send the compressed data
|
||||
if (BLE_compressed_len && BLE_connect(BLE_curr_address, BLE_TYPE_ATC_BLE_OEPL)) {
|
||||
BLE_err_counter = 0;
|
||||
BLE_curr_part = 0;
|
||||
memset(BLE_notify_buffer, 0x00, sizeof(BLE_notify_buffer));
|
||||
|
||||
uint8_t md5bytes[16];
|
||||
MD5Builder md5;
|
||||
md5.begin();
|
||||
md5.add(BLE_image_buffer, BLE_compressed_len);
|
||||
md5.calculate();
|
||||
md5.getBytes(md5bytes);
|
||||
|
||||
BLEavaildatainfo.dataType = dataType;
|
||||
BLEavaildatainfo.dataVer = *((uint64_t*)md5bytes);
|
||||
BLEavaildatainfo.dataSize = BLE_compressed_len;
|
||||
BLEavaildatainfo.dataTypeArgument = dataTypeArgument;
|
||||
BLEavaildatainfo.nextCheckIn = nextCheckin;
|
||||
BLEavaildatainfo.checksum = 0;
|
||||
for (uint16_t c = 1; c < sizeof(struct AvailDataInfo); c++) {
|
||||
BLEavaildatainfo.checksum += (uint8_t)((uint8_t*)&BLEavaildatainfo)[c];
|
||||
}
|
||||
BLE_upload_state = BLE_UPLOAD_STATE_INIT;
|
||||
ble_main_state = BLE_MAIN_STATE_ATC_BLE_OEPL_UPLOAD;
|
||||
BLE_new_notify = true; // trigger the upload here
|
||||
} else {
|
||||
free(BLE_image_buffer);
|
||||
if (BLE_err_counter++ >= 5) { // 5 Retries for a BLE Connection
|
||||
struct espXferComplete reportStruct;
|
||||
memcpy((uint8_t*)&reportStruct.src, BLE_curr_address, 8);
|
||||
processXferComplete(&reportStruct, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // This is a Gicisky display
|
||||
// Here we create the compressed buffer
|
||||
BLE_image_buffer = (uint8_t*)malloc(BUFFER_MAX_SIZE_COMPRESSING);
|
||||
if (BLE_image_buffer == nullptr) {
|
||||
Serial.println("BLE Could not create buffer!");
|
||||
BLE_compressed_len = 0;
|
||||
} else {
|
||||
BLE_compressed_len = compress_image(BLE_curr_address, BLE_image_buffer, BUFFER_MAX_SIZE_COMPRESSING);
|
||||
Serial.printf("BLE Compressed Length: %i\r\n", BLE_compressed_len);
|
||||
// then we connect to BLE to send the compressed data
|
||||
if (BLE_compressed_len && BLE_connect(BLE_curr_address, BLE_TYPE_GICISKY)) {
|
||||
BLE_err_counter = 0;
|
||||
BLE_curr_part = 0;
|
||||
memset(BLE_notify_buffer, 0x00, sizeof(BLE_notify_buffer));
|
||||
BLE_upload_state = BLE_UPLOAD_STATE_INIT;
|
||||
ble_main_state = BLE_MAIN_STATE_UPLOAD;
|
||||
BLE_new_notify = true; // trigger the upload here
|
||||
} else {
|
||||
free(BLE_image_buffer);
|
||||
if (BLE_err_counter++ >= 5) { // 5 Retries for a BLE Connection
|
||||
struct espXferComplete reportStruct;
|
||||
memcpy((uint8_t*)&reportStruct.src, BLE_curr_address, 8);
|
||||
processXferComplete(&reportStruct, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BLE_last_pending_check = millis();
|
||||
@@ -196,25 +320,25 @@ void BLETask(void* parameter) {
|
||||
switch (BLE_upload_state) {
|
||||
default:
|
||||
case BLE_UPLOAD_STATE_INIT:
|
||||
BLE_buff[0] = 1;
|
||||
ctrlChar->writeValue(BLE_buff, 1);
|
||||
BLE_mini_buff[0] = 1;
|
||||
ctrlChar->writeValue(BLE_mini_buff, 1);
|
||||
break;
|
||||
case BLE_UPLOAD_STATE_SIZE:
|
||||
BLE_buff[0] = 0x02;
|
||||
BLE_buff[1] = compressed_len & 0xff;
|
||||
BLE_buff[2] = (compressed_len >> 8) & 0xff;
|
||||
BLE_buff[3] = (compressed_len >> 16) & 0xff;
|
||||
BLE_buff[4] = (compressed_len >> 24) & 0xff;
|
||||
BLE_buff[5] = 0x00;
|
||||
ctrlChar->writeValue(BLE_buff, 6);
|
||||
BLE_mini_buff[0] = 0x02;
|
||||
BLE_mini_buff[1] = BLE_compressed_len & 0xff;
|
||||
BLE_mini_buff[2] = (BLE_compressed_len >> 8) & 0xff;
|
||||
BLE_mini_buff[3] = (BLE_compressed_len >> 16) & 0xff;
|
||||
BLE_mini_buff[4] = (BLE_compressed_len >> 24) & 0xff;
|
||||
BLE_mini_buff[5] = 0x00;
|
||||
ctrlChar->writeValue(BLE_mini_buff, 6);
|
||||
break;
|
||||
case BLE_UPLOAD_STATE_START:
|
||||
BLE_buff[0] = 0x03;
|
||||
ctrlChar->writeValue(BLE_buff, 1);
|
||||
BLE_mini_buff[0] = 0x03;
|
||||
ctrlChar->writeValue(BLE_mini_buff, 1);
|
||||
break;
|
||||
case BLE_UPLOAD_STATE_UPLOAD:
|
||||
if (BLE_notify_buffer[2] == 0x08) {
|
||||
free(buffer);
|
||||
free(BLE_image_buffer);
|
||||
pClient->disconnect();
|
||||
ble_main_state = BLE_MAIN_STATE_IDLE;
|
||||
BLE_last_pending_check = millis();
|
||||
@@ -222,35 +346,103 @@ void BLETask(void* parameter) {
|
||||
struct espXferComplete reportStruct;
|
||||
memcpy((uint8_t*)&reportStruct.src, BLE_curr_address, 8);
|
||||
processXferComplete(&reportStruct, true);
|
||||
curr_part = 0;
|
||||
BLE_err_counter = 0;
|
||||
BLE_curr_part = 0;
|
||||
} else {
|
||||
uint32_t req_curr_part = (BLE_notify_buffer[6] << 24) | (BLE_notify_buffer[5] << 24) | (BLE_notify_buffer[4] << 24) | BLE_notify_buffer[3];
|
||||
if (req_curr_part != curr_part) {
|
||||
Serial.printf("Something went wrong, expected req part: %i but got: %i we better abort here.\r\n", req_curr_part, curr_part);
|
||||
free(buffer);
|
||||
if (req_curr_part != BLE_curr_part) {
|
||||
Serial.printf("Something went wrong, expected req part: %i but got: %i we better abort here.\r\n", req_curr_part, BLE_curr_part);
|
||||
free(BLE_image_buffer);
|
||||
pClient->disconnect();
|
||||
ble_main_state = BLE_MAIN_STATE_IDLE;
|
||||
BLE_last_pending_check = millis();
|
||||
}
|
||||
uint32_t curr_len = 240;
|
||||
if (compressed_len - (curr_part * 240) < 240)
|
||||
curr_len = compressed_len - (curr_part * 240);
|
||||
BLE_buff[0] = curr_part & 0xff;
|
||||
BLE_buff[1] = (curr_part >> 8) & 0xff;
|
||||
BLE_buff[2] = (curr_part >> 16) & 0xff;
|
||||
BLE_buff[3] = (curr_part >> 24) & 0xff;
|
||||
memcpy((uint8_t*)&BLE_buff[4], (uint8_t*)&buffer[curr_part * 240], curr_len);
|
||||
imgChar->writeValue(BLE_buff, curr_len + 4);
|
||||
Serial.printf("BLE sending part: %i\r\n", curr_part);
|
||||
curr_part++;
|
||||
if (BLE_compressed_len - (BLE_curr_part * 240) < 240)
|
||||
curr_len = BLE_compressed_len - (BLE_curr_part * 240);
|
||||
BLE_mini_buff[0] = BLE_curr_part & 0xff;
|
||||
BLE_mini_buff[1] = (BLE_curr_part >> 8) & 0xff;
|
||||
BLE_mini_buff[2] = (BLE_curr_part >> 16) & 0xff;
|
||||
BLE_mini_buff[3] = (BLE_curr_part >> 24) & 0xff;
|
||||
memcpy((uint8_t*)&BLE_mini_buff[4], (uint8_t*)&BLE_image_buffer[BLE_curr_part * 240], curr_len);
|
||||
imgChar->writeValue(BLE_mini_buff, curr_len + 4);
|
||||
Serial.printf("BLE sending part: %i\r\n", BLE_curr_part);
|
||||
BLE_curr_part++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (millis() - BLE_last_notify > 30000) { // Something odd, better reset connection!
|
||||
Serial.println("BLE err going back to IDLE");
|
||||
free(buffer);
|
||||
free(BLE_image_buffer);
|
||||
pClient->disconnect();
|
||||
BLE_err_counter = 0;
|
||||
ble_main_state = BLE_MAIN_STATE_IDLE;
|
||||
BLE_last_pending_check = millis();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BLE_MAIN_STATE_ATC_BLE_OEPL_UPLOAD: {
|
||||
if (BLE_connected && BLE_new_notify) {
|
||||
BLE_new_notify = false;
|
||||
BLE_last_notify = millis();
|
||||
switch (BLE_upload_state) {
|
||||
default:
|
||||
case BLE_UPLOAD_STATE_INIT:
|
||||
BLE_mini_buff[0] = 0x00;
|
||||
BLE_mini_buff[1] = 0x64;
|
||||
memcpy((uint8_t*)&BLE_mini_buff[2], &BLEavaildatainfo, sizeof(struct AvailDataInfo));
|
||||
ctrlChar->writeValue(BLE_mini_buff, sizeof(struct AvailDataInfo) + 2);
|
||||
BLE_upload_state = BLE_UPLOAD_STATE_UPLOAD;
|
||||
break;
|
||||
case BLE_UPLOAD_STATE_UPLOAD: {
|
||||
uint8_t notifyLen = BLE_notify_buffer[0];
|
||||
uint16_t notifyCMD = (BLE_notify_buffer[1] << 8) | BLE_notify_buffer[2];
|
||||
Serial.println("BLE CMD " + String(notifyCMD));
|
||||
switch (notifyCMD) {
|
||||
case BLE_CMD_REQ:
|
||||
if (notifyLen == (sizeof(struct blockRequest) + 2)) {
|
||||
Serial.println("We got a request for a BLK");
|
||||
memcpy(&BLEblkRequst, &BLE_notify_buffer[3], sizeof(struct blockRequest));
|
||||
BLE_curr_part = 0;
|
||||
ATC_BLE_OEPL_PrepareBlk(BLEblkRequst.blockId);
|
||||
ATC_BLE_OEPL_SendPart(BLEblkRequst.blockId, BLE_curr_part);
|
||||
}
|
||||
break;
|
||||
case BLE_CMD_ACK_BLKPRT:
|
||||
BLE_curr_part++;
|
||||
BLE_err_counter = 0;
|
||||
case BLE_CMD_ERR_BLKPRT:
|
||||
if (BLE_curr_part <= BLE_max_block_parts && BLE_err_counter++ < 15) {
|
||||
ATC_BLE_OEPL_SendPart(BLEblkRequst.blockId, BLE_curr_part);
|
||||
break;
|
||||
} // FALLTROUGH!!! We cancel the upload if we land here since we dont have so many parts of a block!
|
||||
case BLE_CMD_ACK:
|
||||
case BLE_CMD_ACK_IS_SHOWN:
|
||||
case BLE_CMD_ACK_FW_UPDATED:
|
||||
Serial.println("BLE Upload done");
|
||||
free(BLE_image_buffer);
|
||||
pClient->disconnect();
|
||||
ble_main_state = BLE_MAIN_STATE_IDLE;
|
||||
BLE_last_pending_check = millis();
|
||||
// Done and the image is refreshing now
|
||||
struct espXferComplete reportStruct;
|
||||
memcpy((uint8_t*)&reportStruct.src, BLE_curr_address, 8);
|
||||
processXferComplete(&reportStruct, true);
|
||||
BLE_err_counter = 0;
|
||||
BLE_max_block_parts = 0;
|
||||
BLE_curr_part = 0;
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
if (millis() - BLE_last_notify > 30000) { // Something odd, better reset connection!
|
||||
Serial.println("BLE err going back to IDLE");
|
||||
free(BLE_image_buffer);
|
||||
pClient->disconnect();
|
||||
BLE_err_counter = 0;
|
||||
ble_main_state = BLE_MAIN_STATE_IDLE;
|
||||
BLE_last_pending_check = millis();
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
#define CAPABILITY_HAS_WAKE_BUTTON 0x20
|
||||
#define CAPABILITY_HAS_NFC 0x40
|
||||
#define CAPABILITY_NFC_WAKE 0x80
|
||||
#define CAPABILITY_IS_BLE 0x0100
|
||||
|
||||
#define DATATYPE_NOUPDATE 0
|
||||
#define DATATYPE_IMG_BMP 2 // ** deprecated
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#define CAPABILITY_HAS_WAKE_BUTTON 0x20
|
||||
#define CAPABILITY_HAS_NFC 0x40
|
||||
#define CAPABILITY_NFC_WAKE 0x80
|
||||
#define CAPABILITY_IS_BLE 0x0100
|
||||
|
||||
#define DATATYPE_NOUPDATE 0
|
||||
#define DATATYPE_IMG_BMP 2
|
||||
|
||||
Reference in New Issue
Block a user