SingingCat 0
application
esp32_bluetooth.c
1#include "main-header.h"
2#include "espressif/esp8266_flash.h"
3#include "shifter.h"
4#include "espressif/esp32_bluetooth.h"
5static struct bt_peer_info peer_info;
6static struct shifter shifty;
7static struct command *bt_get_reply() {
8 struct command *dcom = get_data_reply(peer_info.bt_peer_com);
9
10 if (dcom == NULL) {
11 peer_info.valid = 0;
12 return NULL;
13 }
14 dcom->recipient = peer_info.bt_peer_com->target;
15 dcom->flags = COMFLAGS_DATA | COMFLAGS_SUCCESS;
16 return dcom;
17}
18static void bt_peer_update_finished(const uint8_t *buf, int size) {
19 int sent_peers = buf[6];
20
21 printf("[bt-peer-update] final ack for (received %i peers, esp32 sent %i peers)\r\n", peer_info.peercount, sent_peers);
22
23 int i;
24 struct command *com = NULL;
25 int peers_in_com = 0;
26
27 for (i = 0; i < MAX_BT_PEERS; i++) {
28 struct bt_peer *peer = &peer_info.peers[i];
29 if (peer->mac == 0) {
30 continue;
31 }
32
33 if (peers_in_com > 5) {
34 deliver_command(com, NULL);
35 com = NULL;
36 peers_in_com = 0;
37 }
38
39 if (com == NULL) {
40 com = bt_get_reply();
41 if (com == NULL) {
42 printf("[bt-peer-update] no command allocatable\r\n");
43 break;
44 }
45 }
46
47 uint8_t bbuf[100];
48 struct shifter *sh = &shifty;
49 shifter_init(sh, (uint8_t *)&bbuf, 90);
50 shift_into_uint64(sh, peer->mac);
51 shift_into_uint8(sh, strlen(peer->name));
52 int j;
53 for (j = 0; j < strlen(peer->name); j++) {
54 shift_into_uint8(sh, peer->name[j]);
55 }
56 if (shift_error(sh)) {
57 printf("[bt-peer-update] Shift error: %i\r\n", shift_error(sh));
58 continue;
59 }
60 peers_in_com++;
61 command_add_binary_arg(com, shift_size(sh), (const byte *)bbuf);
62 }
63 if (com != NULL) {
64 deliver_command(com, NULL);
65 }
66 //last one
67 struct command *dcom = get_data_reply(peer_info.bt_peer_com);
68
69 if (dcom == NULL) {
70 peer_info.valid = 0;
71 return;
72 }
73 dcom->recipient = peer_info.bt_peer_com->target;
74 dcom->flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
75 command_add_arg(dcom, "peers=%i", peer_info.peercount);
76 command_add_arg(dcom, "btpeers=%i", sent_peers);
77 deliver_command(dcom, NULL);
78 free_command(peer_info.bt_peer_com);
79 peer_info.valid = 0;
80 return;
81}
82static void bt_peer_update_continue(const uint8_t *buf, int size) {
83 peer_info.peercount++;
84
85 int nc = 0;
86 struct bt_peer *peer = NULL;
87
88 for (nc = 0; nc < MAX_BT_PEERS; nc++) {
89 struct bt_peer *p = &peer_info.peers[nc];
90 if (p->mac == 0) {
91 peer = p;
92 break;
93 }
94 }
95 if (peer == NULL) {
96 printf("[bt-peer-update] No more peer spaces\r\n");
97 return;
98 }
99 peer->mac = 0;
100 peer->name[0] = 0;
101 nc = 0;
102 uint32_t seq = 0;
103
104 seq |= (((uint32_t)buf[nc++]) << (1 * 24));
105 seq |= (((uint32_t)buf[nc++]) << (1 * 16));
106 seq |= (((uint32_t)buf[nc++]) << (1 * 8));
107 seq |= buf[nc++];
108
109 nc++; // idx
110 nc++; // follows
111 int i;
112
113 for (i = 0; i < 6; i++) {
114 peer->mac = peer->mac << 8;
115 peer->mac = peer->mac | buf[nc++];
116 }
117 int nl = buf[nc++];
118
119 if (nl >= sizeof(peer->name)) {
120 nl = sizeof(peer->name) - 1;
121 }
122 for (i = 0; i < nl; i++) {
123 peer->name[i] = buf[nc++];
124 }
125 peer->name[i] = 0;
126 // printf("[bt-peer-update] sequence: idx=%i,seq=%p,nc=%i,mac=\"%s\",name=\"%s\"\r\n",idx,seq,nc,nbuf,cbuf);
127}
128
129// received a peer update message
130void bt_peer_update(const uint8_t *buf, int size) {
131 int idx = buf[4];
132 int follows = buf[5];
133
134 printf("[bt-peer-update] received (idx=%i,follows=%i):\r\n", idx, follows);
135 printHex(" ", buf, size);
136 if (peer_info.valid == 0) {
137 printf("[bt-peer-update] received, but no trigger command\r\n");
138 return;
139 }
140
141 if (follows == 0) {
142 bt_peer_update_finished(buf, size);
143 } else {
144 bt_peer_update_continue(buf, size);
145 }
146}
147
148
149// request bt peers
150int esp32_bt_peers(struct command *com) {
151 peer_info.bt_peer_com = get_data_reply(com);
152 if (peer_info.bt_peer_com == NULL) {
153 return 2;
154 }
155 peer_info.peercount = 0;
156 peer_info.valid = 1;
157 int i;
158
159 for (i = 0; i < MAX_BT_PEERS; i++) {
160 struct bt_peer *peer = &peer_info.peers[i];
161 peer->mac = 0;
162 }
163 printf("Trigger to get bt peers:\r\n");
164 command_print(peer_info.bt_peer_com);
165 uint8_t buf[4];
166
167 buf[0] = com->index && 0xff;
168 buf[1] = (com->index >> (1 * 8)) && 0xff;
169 buf[2] = (com->index >> (2 * 8)) && 0xff;
170 buf[3] = (com->index >> (3 * 8)) && 0xff;
171 cat_send_local_instruction(INSTRUCTION_BT_BLE_GET_PEERS, buf, 4);
172 return 0;
173}
174// 00 == ok, bluetooth BLE write a characteristic
175int esp32_bt_set_characteristic_com(struct command *com) {
176 uint8_t buf[300];
177 int j;
178 int i;
179
180 j = 0;
181
182 const char *argbuf = get_arg(com, 0); // mac
183 int ac = get_arg_size(com, 0);
184
185 if (ac != 6) {
186 printf("esp8266: invalid argument size #0 (should be 6, is %i)\r\n", ac);
187 return 2;
188 }
189 for (i = 0; i < 6; i++) {
190 buf[j++] = argbuf[i];
191 }
192
193 argbuf = get_arg(com, 1); // handle
194 ac = get_arg_size(com, 1);
195 if (ac != 2) {
196 printf("esp8266: invalid argument size #1 (should be 2, is %i)\r\n", ac);
197 return 2;
198 }
199 buf[j++] = argbuf[0];
200 buf[j++] = argbuf[1];
201
202 argbuf = get_arg(com, 2); // value
203 ac = get_arg_size(com, 2);
204 int avail = sizeof(buf) - 10;
205
206 if ((ac + j) > avail) {
207 printf("esp8266: Invalid argument size #2 (too long %i bytes), available: %i\n", ac, avail - j);
208 return 2;
209 }
210 for (i = 0; i < ac; i++) {
211 buf[j++] = argbuf[i];
212 }
213 cat_send_local_instruction(INSTRUCTION_BT_BLE_WRITE_CHAR, buf, j);
214 return 1;
215}
216/*
217 * triggers a "read characteristic". esp32 is supposed to send a command to us with the value once it received it from the remove device
218 */
219int esp32_bt_trigger_read_characteristic_com(struct command *com) {
220 uint8_t buf[300];
221 int j;
222 int i;
223
224 j = 0;
225
226 const char *argbuf = get_arg(com, 0); // mac
227 int ac = get_arg_size(com, 0);
228
229 if (ac != 6) {
230 printf("esp8266: invalid argument size #0 (should be 6, is %i)\r\n", ac);
231 return 2;
232 }
233 for (i = 0; i < 6; i++) {
234 buf[j++] = argbuf[i];
235 }
236
237 argbuf = get_arg(com, 1); // handle
238 ac = get_arg_size(com, 1);
239 if (ac != 2) {
240 printf("esp8266: invalid argument size #1 (should be 2, is %i)\r\n", ac);
241 return 2;
242 }
243 buf[j++] = argbuf[0];
244 buf[j++] = argbuf[1];
245
246
247 cat_send_local_instruction(INSTRUCTION_BT_BLE_READ_CHAR, buf, j);
248 return 1;
249}
void free_command(struct command *com)
free a command
Definition: queue.c:200
int deliver_command(struct command *com, pkt_callback)
deliver a command to a module
Definition: queue.c:651
void command_add_arg(struct command *com, const char *format,...)
adds an arg to a partially initialised command structure
void cat_send_local_instruction(const PACKET_TYPE type, const uint8_t *buf, const int len)
send a packet to the esp8266 wifi chip
Definition: esp8266.c:1343
struct command * get_data_reply(struct command *com)
allocates and initializes a packet to be send as "data" to the command typically you'd add some data ...
Definition: queue.c:271
void command_print(struct command *com)
prints a command in human readable format to serial console
int command_add_binary_arg(struct command *com, const int len, const byte *srcbuf)
adds a binary parameter to command returns 0 if ok otherwise errorcode
const char * get_arg(const struct command *com, int index)
given an argument by index[0..n], will return a pointer to the bytearray (excluding the fieldtype) th...
int get_arg_size(const struct command *com, int index)
given an argument by index [0..n], will returns the size of the value in bytes. for a string/array it...
int com
Definition: command.h:22
long target
Definition: command.h:16
long recipient
Definition: command.h:15
int index
Definition: command.h:13
uint8_t flags
Definition: command.h:23
Definition: shifter.h:6