-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBulkTransferService.h
More file actions
176 lines (152 loc) · 5.46 KB
/
Copy pathBulkTransferService.h
File metadata and controls
176 lines (152 loc) · 5.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
* BulkTransferService.h
*
* Created on: 2016-02-02
* Author: KUANG Qi
*/
#ifndef __BLE_BULK_TRANSFER_SERVICE_H__
#define __BLE_BULK_TRANSFER_SERVICE_H__
#include "ble/BLE.h"
typedef void (*RequestCallback)(int addr, int len);
#define PAYLOAD_SIZE 16
#define UUID_BULK_DATA 0x1111
#define UUID_BULK_CONTROL_POINT 0x2222
class BulkTransferService
{
public:
//typedef void (*callback_t)(AlertLevel_t level);
/**
* @param[ref] ble
* BLE object for the underlying controller.
*/
BulkTransferService(BLE &bleIn, uint8_t *dataBuffer, int bufSize, RequestCallback callback) :
ble(bleIn),
bufferBase(dataBuffer),
bufferCursor(dataBuffer),
bulkTransferData(UUID_BULK_DATA, bufferCursor, PAYLOAD_SIZE, PAYLOAD_SIZE, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
bulkTransferControlPoint(UUID_BULK_CONTROL_POINT, (uint8_t *)controlPointBase, 8, 8, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)
{
static bool serviceAdded = false; /* We should only ever add one Immediate Alert service. */
bufferSize = bufSize;
requestData = callback;
lengthRequested = 0;
addressRequested = 0;
bytesInBuffer = 0;
bytesInTransaction = 0;
addressCursor = 0;
isSubscibed = false;
if (serviceAdded)
{
return;
}
GattCharacteristic *charTable[] = {&bulkTransferData, &bulkTransferControlPoint};
GattService bulkTransferService(0x1825, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
ble.gattServer().addService(bulkTransferService);
serviceAdded = true;
ble.gattServer().onDataWritten(this, &BulkTransferService::onDataWritten);
ble.gattServer().onDataSent(this, &BulkTransferService::onDataSent);
ble.gattServer().onUpdatesEnabled(FunctionPointerWithContext<uint16_t>(this, &BulkTransferService::onUpdatesEnabled));
ble.gattServer().onUpdatesDisabled(FunctionPointerWithContext<uint16_t>(this, &BulkTransferService::onUpdatesDisables));
}
uint32_t getAddress()
{
return addressRequested;
}
uint32_t getLength()
{
return lengthRequested;
}
void dataPrepared(int length)
{
if(isSubscibed)
{
bytesInBuffer = length;
bufferCursor = bufferBase;
sendBuffer();
}
}
protected:
/**
* This callback allows receiving updates to the Bulk Transfer Control Point characteristic.
*
* @param[in] params
* Information about the characteristic being updated.
*/
virtual void onDataWritten(const GattWriteCallbackParams *params)
{
if (params->handle == bulkTransferControlPoint.getValueHandle())
{
uint8_t *ptr = (uint8_t *)controlPointBase;
for(int i = 0; i < 8; i++) ptr[i] = params->data[i];
addressRequested = controlPointBase[0];
lengthRequested = controlPointBase[1];
addressCursor = addressRequested;
bytesInTransaction = lengthRequested;
if(bytesInTransaction > 0)
{
printf("%d bytes of data from 0x%06x are requested\r\n", lengthRequested, addressRequested);
requestData(addressCursor, bytesInTransaction < bufferSize ? bytesInTransaction : bufferSize);
}
}
}
void onDataSent(unsigned count)
{
sendBuffer();
}
virtual void onUpdatesEnabled(uint16_t handle)
{
if(handle == bulkTransferData.getValueHandle()) isSubscibed = true;
}
virtual void onUpdatesDisables(uint16_t handle)
{
if(handle == bulkTransferData.getValueHandle()) isSubscibed = false;
}
virtual void sendBuffer()
{
int len;
ble_error_t didSendValue = BLE_ERROR_NONE;
while(bytesInBuffer > 0)
{
len = bytesInBuffer < PAYLOAD_SIZE ? bytesInBuffer : PAYLOAD_SIZE;
didSendValue = ble.gattServer().write(bulkTransferData.getValueHandle(), bufferCursor, len);
if(didSendValue != BLE_ERROR_NONE) break;
//for(int i = 0; i < len; i++) printf("%x", (int)bufferCursor[i]);
//printf("\r\n");
bufferCursor += len;
bytesInBuffer -= len;
bytesInTransaction -= len;
addressCursor += len;
}
if(bytesInTransaction != 0 && bytesInBuffer == 0)
{
requestData(addressCursor, bytesInTransaction < bufferSize ? bytesInTransaction : bufferSize);
}
}
protected:
BLE &ble;
// Pointer to the data buffer
uint8_t *bufferBase;
// Cursor to the data buffer
uint8_t *bufferCursor;
// Length of the data buffer
int bufferSize;
// Memory of Bulk Transfer Control Point
uint32_t controlPointBase[2]; // [0]: address [1]: length
// Address of data (in flash) which are requested by the client
int addressRequested;
// A cursor of data (in flash)
int addressCursor;
// Length of data (in flash) which are requested by the client
int lengthRequested;
// Number of bytes to be sent in the buffer
int bytesInBuffer;
// Number of bytes to be sent in a requested transaction
int bytesInTransaction;
// Characteristic Bulk Transfer Data is subscribed by client
bool isSubscibed;
// BLE characteristics
GattCharacteristic bulkTransferData;
GattCharacteristic bulkTransferControlPoint;
RequestCallback requestData;
};
#endif /* __BLE_BULK_TRANSFER_SERVICE_H__ */