19 #define DEBUG // Uncomment to print data for debugging
27 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
28 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
29 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
30 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
31 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
32 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
33 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
34 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
35 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
36 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
37 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
38 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
39 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
40 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
41 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
42 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
57 rfcomm_dcid[0] = 0x51;
58 rfcomm_dcid[1] = 0x00;
65 RFCOMMConnected =
false;
78 if (RFCOMMConnected && SDPConnected)
99 if (((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000))) {
100 if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) {
103 Notify(PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
104 PrintHex<uint8_t > (l2capinbuf[13], 0x80);
106 PrintHex<uint8_t > (l2capinbuf[12], 0x80);
107 Notify(PSTR(
" Data: "), 0x80);
108 PrintHex<uint8_t > (l2capinbuf[17], 0x80);
110 PrintHex<uint8_t > (l2capinbuf[16], 0x80);
112 PrintHex<uint8_t > (l2capinbuf[15], 0x80);
114 PrintHex<uint8_t > (l2capinbuf[14], 0x80);
118 Notify(PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
119 PrintHex<uint8_t > (l2capinbuf[13], 0x80);
121 PrintHex<uint8_t > (l2capinbuf[12], 0x80);
122 Notify(PSTR(
" SCID: "), 0x80);
123 PrintHex<uint8_t > (l2capinbuf[15], 0x80);
125 PrintHex<uint8_t > (l2capinbuf[14], 0x80);
126 Notify(PSTR(
" Identifier: "), 0x80);
127 PrintHex<uint8_t > (l2capinbuf[9], 0x80);
129 if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
SDP_PSM) {
130 identifier = l2capinbuf[9];
131 sdp_scid[0] = l2capinbuf[14];
132 sdp_scid[1] = l2capinbuf[15];
134 }
else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
RFCOMM_PSM) {
135 identifier = l2capinbuf[9];
136 rfcomm_scid[0] = l2capinbuf[14];
137 rfcomm_scid[1] = l2capinbuf[15];
141 if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
142 if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
145 }
else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
151 if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
153 identifier = l2capinbuf[9];
155 }
else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
157 identifier = l2capinbuf[9];
161 if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
163 identifier = l2capinbuf[9];
165 }
else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
167 identifier = l2capinbuf[9];
171 if (l2capinbuf[12] == sdp_scid[0] && l2capinbuf[13] == sdp_scid[1]) {
173 identifier = l2capinbuf[9];
175 }
else if (l2capinbuf[12] == rfcomm_scid[0] && l2capinbuf[13] == rfcomm_scid[1]) {
177 identifier = l2capinbuf[9];
182 Notify(PSTR(
"\r\nInformation request"), 0x80);
184 identifier = l2capinbuf[9];
189 Notify(PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
190 PrintHex<uint8_t > (l2capinbuf[8], 0x80);
193 }
else if (l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) {
195 if (((l2capinbuf[16] << 8 | l2capinbuf[17]) ==
SERIALPORT_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) ==
SERIALPORT_UUID)) {
197 serialPortResponse1(l2capinbuf[9], l2capinbuf[10]);
198 firstMessage =
false;
200 serialPortResponse2(l2capinbuf[9], l2capinbuf[10]);
203 }
else if (((l2capinbuf[16] << 8 | l2capinbuf[17]) ==
L2CAP_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) ==
L2CAP_UUID)) {
205 l2capResponse1(l2capinbuf[9], l2capinbuf[10]);
206 firstMessage =
false;
208 l2capResponse2(l2capinbuf[9], l2capinbuf[10]);
212 serviceNotSupported(l2capinbuf[9], l2capinbuf[10]);
214 Notify(PSTR(
"\r\nUUID: "), 0x80);
216 if((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000)
217 uuid = (l2capinbuf[18] << 8 | l2capinbuf[19]);
219 uuid = (l2capinbuf[16] << 8 | l2capinbuf[17]);
220 PrintHex<uint16_t> (uuid, 0x80);
222 Notify(PSTR(
"\r\nLength: "), 0x80);
223 uint16_t length = l2capinbuf[11] << 8 | l2capinbuf[12];
224 PrintHex<uint16_t> (length, 0x80);
225 Notify(PSTR(
"\r\nData: "), 0x80);
226 for (uint8_t i = 0; i < length; i++) {
227 PrintHex<uint8_t> (l2capinbuf[13+i], 0x80);
232 }
else if (l2capinbuf[6] == rfcomm_dcid[0] && l2capinbuf[7] == rfcomm_dcid[1]) {
233 rfcommChannel = l2capinbuf[8] & 0xF8;
234 rfcommDirection = l2capinbuf[8] & 0x04;
235 rfcommCommandResponse = l2capinbuf[8] & 0x02;
236 rfcommChannelType = l2capinbuf[9] & 0xEF;
237 rfcommPfBit = l2capinbuf[9] & 0x10;
239 if (rfcommChannel >> 3 != 0x00)
240 rfcommChannelConnection = rfcommChannel;
243 Notify(PSTR(
"\r\nRFCOMM Channel: "), 0x80);
244 PrintHex<uint8_t > (rfcommChannel >> 3, 0x80);
245 Notify(PSTR(
" Direction: "), 0x80);
246 PrintHex<uint8_t > (rfcommDirection >> 2, 0x80);
247 Notify(PSTR(
" CommandResponse: "), 0x80);
248 PrintHex<uint8_t > (rfcommCommandResponse >> 1, 0x80);
249 Notify(PSTR(
" ChannelType: "), 0x80);
250 PrintHex<uint8_t > (rfcommChannelType, 0x80);
251 Notify(PSTR(
" PF_BIT: "), 0x80);
252 PrintHex<uint8_t > (rfcommPfBit, 0x80);
256 Notify(PSTR(
"\r\nReceived Disconnect RFCOMM Command on channel: "), 0x80);
257 PrintHex<uint8_t > (rfcommChannel >> 3, 0x80);
260 sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse,
RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00);
264 if (rfcommChannelType ==
RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) {
265 uint8_t length = l2capinbuf[10] >> 1;
266 uint8_t offset = l2capinbuf[4] - length - 4;
267 if (rfcommAvailable + length <=
sizeof (rfcommDataBuffer)) {
268 for (uint8_t i = 0; i < length; i++)
269 rfcommDataBuffer[rfcommAvailable + i] = l2capinbuf[11 + i + offset];
270 rfcommAvailable += length;
273 Notify(PSTR(
"\r\nRFCOMM Data Available: "), 0x80);
274 Notify(rfcommAvailable, 0x80);
276 Notify(PSTR(
" - Credit: 0x"), 0x80);
277 PrintHex<uint8_t > (l2capinbuf[11], 0x80);
280 #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth
281 for (uint8_t i = 0; i < length; i++)
282 Notifyc(l2capinbuf[i + 11 + offset], 0x80);
286 Notify(PSTR(
"\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
289 rfcommbuf[1] = l2capinbuf[12];
290 rfcommbuf[2] = l2capinbuf[13];
291 rfcommbuf[3] = l2capinbuf[14];
292 rfcommbuf[4] = l2capinbuf[15];
293 rfcommbuf[5] = l2capinbuf[16];
294 rfcommbuf[6] = l2capinbuf[17];
295 rfcommbuf[7] = l2capinbuf[18];
296 rfcommbuf[8] = l2capinbuf[19];
297 rfcommbuf[9] = l2capinbuf[20];
298 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
301 Notify(PSTR(
"\r\nSend UIH Modem Status Response"), 0x80);
304 rfcommbuf[1] = 2 << 1 | 1;
305 rfcommbuf[2] = l2capinbuf[13];
306 rfcommbuf[3] = l2capinbuf[14];
307 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
312 Notify(PSTR(
"\r\nReceived SABM Command"), 0x80);
314 sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse,
RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00);
317 Notify(PSTR(
"\r\nReceived UIH Parameter Negotiation Command"), 0x80);
320 rfcommbuf[1] = l2capinbuf[12];
321 rfcommbuf[2] = l2capinbuf[13];
329 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
332 Notify(PSTR(
"\r\nSend UIH Modem Status Response"), 0x80);
335 rfcommbuf[1] = 2 << 1 | 1;
336 rfcommbuf[2] = l2capinbuf[13];
337 rfcommbuf[3] = l2capinbuf[14];
338 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
342 Notify(PSTR(
"\r\nSend UIH Modem Status Command"), 0x80);
345 rfcommbuf[1] = 2 << 1 | 1;
346 rfcommbuf[2] = l2capinbuf[13];
349 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
353 Notify(PSTR(
"\r\nSend UIH Command with credit"), 0x80);
355 sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0,
RFCOMM_UIH, 0x10,
sizeof (rfcommDataBuffer));
358 waitForLastCommand =
true;
360 }
else if (rfcommChannelType ==
RFCOMM_UIH && l2capinbuf[10] == 0x01) {
362 Notify(PSTR(
"\r\nReceived UIH Command with credit"), 0x80);
366 Notify(PSTR(
"\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
369 rfcommbuf[1] = l2capinbuf[12];
370 rfcommbuf[2] = l2capinbuf[13];
371 rfcommbuf[3] = l2capinbuf[14];
372 rfcommbuf[4] = l2capinbuf[15];
373 rfcommbuf[5] = l2capinbuf[16];
374 rfcommbuf[6] = l2capinbuf[17];
375 rfcommbuf[7] = l2capinbuf[18];
376 rfcommbuf[8] = l2capinbuf[19];
377 rfcommbuf[9] = l2capinbuf[20];
378 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
380 Notify(PSTR(
"\r\nRFCOMM Connection is now established\r\n"), 0x80);
382 waitForLastCommand =
false;
389 Notify(PSTR(
"\r\nUnsupported RFCOMM Data - ChannelType: "), 0x80);
390 PrintHex<uint8_t > (rfcommChannelType, 0x80);
391 Notify(PSTR(
" Command: "), 0x80);
392 PrintHex<uint8_t > (l2capinbuf[11], 0x80);
399 Notify(PSTR(
"\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
400 PrintHex<uint8_t > (l2capinbuf[7], 0x80);
402 PrintHex<uint8_t > (l2capinbuf[6], 0x80);
411 if (waitForLastCommand && (millis() - timer) > 100) {
413 Notify(PSTR(
"\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
416 waitForLastCommand =
false;
423 void SPP::SDP_task() {
424 switch (l2cap_sdp_state) {
429 Notify(PSTR(
"\r\nSDP Incoming Connection Request"), 0x80);
444 Notify(PSTR(
"\r\nSDP Configuration Request"), 0x80);
454 Notify(PSTR(
"\r\nSDP Successfully Configured"), 0x80);
464 SDPConnected =
false;
466 Notify(PSTR(
"\r\nDisconnected SDP Channel"), 0x80);
476 Notify(PSTR(
"\r\nDisconnected L2CAP Connection"), 0x80);
478 RFCOMMConnected =
false;
479 SDPConnected =
false;
482 l2cap_event_flag = 0;
490 void SPP::RFCOMM_task() {
491 switch (l2cap_rfcomm_state) {
496 Notify(PSTR(
"\r\nRFCOMM Incoming Connection Request"), 0x80);
511 Notify(PSTR(
"\r\nRFCOMM Configuration Request"), 0x80);
521 Notify(PSTR(
"\r\nRFCOMM Successfully Configured"), 0x80);
525 RFCOMMConnected =
true;
532 RFCOMMConnected =
false;
535 Notify(PSTR(
"\r\nDisconnected RFCOMM Channel"), 0x80);
548 void SPP::SDP_Command(uint8_t* data, uint8_t nbytes) {
549 pBtd->
L2CAP_Command(hci_handle, data, nbytes, sdp_scid[0], sdp_scid[1]);
552 void SPP::serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
554 l2capoutbuf[1] = transactionIDHigh;
555 l2capoutbuf[2] = transactionIDLow;
556 l2capoutbuf[3] = 0x00;
557 l2capoutbuf[4] = 0x05;
558 l2capoutbuf[5] = 0x00;
559 l2capoutbuf[6] = 0x02;
562 l2capoutbuf[7] = 0x35;
563 l2capoutbuf[8] = 0x00;
564 l2capoutbuf[9] = 0x00;
566 SDP_Command(l2capoutbuf, 10);
569 void SPP::serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
571 l2capoutbuf[1] = transactionIDHigh;
572 l2capoutbuf[2] = transactionIDLow;
573 l2capoutbuf[3] = 0x00;
574 l2capoutbuf[4] = 0x2B;
575 l2capoutbuf[5] = 0x00;
576 l2capoutbuf[6] = 0x26;
579 l2capoutbuf[7] = 0x36;
580 l2capoutbuf[8] = 0x00;
581 l2capoutbuf[9] = 0x3C;
582 l2capoutbuf[10] = 0x36;
583 l2capoutbuf[11] = 0x00;
585 l2capoutbuf[12] = 0x39;
586 l2capoutbuf[13] = 0x09;
587 l2capoutbuf[14] = 0x00;
588 l2capoutbuf[15] = 0x00;
589 l2capoutbuf[16] = 0x0A;
590 l2capoutbuf[17] = 0x00;
591 l2capoutbuf[18] = 0x01;
592 l2capoutbuf[19] = 0x00;
593 l2capoutbuf[20] = 0x06;
594 l2capoutbuf[21] = 0x09;
595 l2capoutbuf[22] = 0x00;
596 l2capoutbuf[23] = 0x01;
597 l2capoutbuf[24] = 0x35;
598 l2capoutbuf[25] = 0x03;
599 l2capoutbuf[26] = 0x19;
600 l2capoutbuf[27] = 0x11;
602 l2capoutbuf[28] = 0x01;
603 l2capoutbuf[29] = 0x09;
604 l2capoutbuf[30] = 0x00;
605 l2capoutbuf[31] = 0x04;
606 l2capoutbuf[32] = 0x35;
607 l2capoutbuf[33] = 0x0C;
608 l2capoutbuf[34] = 0x35;
609 l2capoutbuf[35] = 0x03;
610 l2capoutbuf[36] = 0x19;
611 l2capoutbuf[37] = 0x01;
612 l2capoutbuf[38] = 0x00;
613 l2capoutbuf[39] = 0x35;
614 l2capoutbuf[40] = 0x05;
615 l2capoutbuf[41] = 0x19;
616 l2capoutbuf[42] = 0x00;
617 l2capoutbuf[43] = 0x03;
619 l2capoutbuf[44] = 0x08;
620 l2capoutbuf[45] = 0x02;
621 l2capoutbuf[46] = 0x00;
622 l2capoutbuf[47] = 0x19;
624 SDP_Command(l2capoutbuf, 48);
627 void SPP::serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
629 l2capoutbuf[1] = transactionIDHigh;
630 l2capoutbuf[2] = transactionIDLow;
631 l2capoutbuf[3] = 0x00;
632 l2capoutbuf[4] = 0x1C;
633 l2capoutbuf[5] = 0x00;
634 l2capoutbuf[6] = 0x19;
637 l2capoutbuf[7] = 0x01;
638 l2capoutbuf[8] = 0x09;
639 l2capoutbuf[9] = 0x00;
640 l2capoutbuf[10] = 0x06;
641 l2capoutbuf[11] = 0x35;
643 l2capoutbuf[12] = 0x09;
644 l2capoutbuf[13] = 0x09;
645 l2capoutbuf[14] = 0x65;
646 l2capoutbuf[15] = 0x6E;
647 l2capoutbuf[16] = 0x09;
648 l2capoutbuf[17] = 0x00;
649 l2capoutbuf[18] = 0x6A;
650 l2capoutbuf[19] = 0x09;
651 l2capoutbuf[20] = 0x01;
652 l2capoutbuf[21] = 0x00;
653 l2capoutbuf[22] = 0x09;
654 l2capoutbuf[23] = 0x01;
655 l2capoutbuf[24] = 0x00;
656 l2capoutbuf[25] = 0x25;
658 l2capoutbuf[26] = 0x05;
659 l2capoutbuf[27] =
'T';
660 l2capoutbuf[28] =
'K';
661 l2capoutbuf[29] =
'J';
662 l2capoutbuf[30] =
'S';
663 l2capoutbuf[31] =
'P';
664 l2capoutbuf[32] = 0x00;
666 SDP_Command(l2capoutbuf, 33);
669 void SPP::l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
670 serialPortResponse1(transactionIDHigh, transactionIDLow);
673 void SPP::l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
674 serialPortResponse2(transactionIDHigh, transactionIDLow);
680 void SPP::RFCOMM_Command(uint8_t* data, uint8_t nbytes) {
681 pBtd->
L2CAP_Command(hci_handle, data, nbytes, rfcomm_scid[0], rfcomm_scid[1]);
684 void SPP::sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length) {
686 l2capoutbuf[1] = channelType | pfBit;
687 l2capoutbuf[2] = length << 1 | 0x01;
689 for (; i < length; i++)
690 l2capoutbuf[i + 3] = data[i];
691 l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
693 Notify(PSTR(
" - RFCOMM Data: "), 0x80);
694 for (i = 0; i < length + 4; i++) {
695 PrintHex<uint8_t > (l2capoutbuf[i], 0x80);
699 RFCOMM_Command(l2capoutbuf, length + 4);
702 void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit) {
704 l2capoutbuf[1] = channelType | pfBit;
705 l2capoutbuf[2] = 0x01;
706 l2capoutbuf[3] = credit;
707 l2capoutbuf[4] = calcFcs(l2capoutbuf);
709 Notify(PSTR(
" - RFCOMM Credit Data: "), 0x80);
710 for (uint8_t i = 0; i < 5; i++) {
711 PrintHex<uint8_t > (l2capoutbuf[i], 0x80);
715 RFCOMM_Command(l2capoutbuf, 5);
719 uint8_t SPP::__crc(uint8_t* data) {
724 uint8_t SPP::calcFcs(uint8_t *data) {
726 return (0xff - __crc(data));
733 return write(&data,1);
737 for(uint8_t i = 0; i < size; i++) {
738 if(sppIndex >=
sizeof(sppOutputBuffer)/
sizeof(sppOutputBuffer[0]))
740 sppOutputBuffer[sppIndex++] = data[i];
751 l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 |
extendAddress;
755 if (sppIndex > (
sizeof (l2capoutbuf) - 4))
756 length =
sizeof (l2capoutbuf) - 4;
760 l2capoutbuf[2] = length << 1 | 1;
762 for (; i < length; i++)
763 l2capoutbuf[i + 3] = sppOutputBuffer[i + offset];
764 l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
766 RFCOMM_Command(l2capoutbuf, length + 4);
774 return rfcommAvailable;
782 if (rfcommAvailable == 0)
784 return rfcommDataBuffer[0];
788 if (rfcommAvailable == 0)
790 uint8_t output = rfcommDataBuffer[0];
791 for (uint8_t i = 1; i < rfcommAvailable; i++)
792 rfcommDataBuffer[i - 1] = rfcommDataBuffer[i];
795 if (bytesRead > (
sizeof (rfcommDataBuffer) - 5)) {
797 sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0,
RFCOMM_UIH, 0x10,
sizeof (rfcommDataBuffer));
799 Notify(PSTR(
"\r\nSent "), 0x80);
800 Notify((uint8_t)
sizeof (rfcommDataBuffer), 0x80);
801 Notify(PSTR(
" more credit"), 0x80);