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) {
102 #ifdef DEBUG_USB_HOST
103 Notify(PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
104 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
106 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
107 Notify(PSTR(
" Data: "), 0x80);
108 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
110 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
112 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
114 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
118 Notify(PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
119 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
121 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
122 Notify(PSTR(
" SCID: "), 0x80);
123 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
125 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
126 Notify(PSTR(
" Identifier: "), 0x80);
127 D_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];
181 #ifdef DEBUG_USB_HOST
182 Notify(PSTR(
"\r\nInformation request"), 0x80);
184 identifier = l2capinbuf[9];
189 Notify(PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
190 D_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 D_PrintHex<uint16_t> (uuid, 0x80);
222 Notify(PSTR(
"\r\nLength: "), 0x80);
223 uint16_t length = l2capinbuf[11] << 8 | l2capinbuf[12];
224 D_PrintHex<uint16_t> (length, 0x80);
225 Notify(PSTR(
"\r\nData: "), 0x80);
226 for (uint8_t i = 0; i < length; i++) {
227 D_PrintHex<uint8_t> (l2capinbuf[13+i], 0x80);
234 Notify(PSTR(
"\r\nUnknown PDU: "));
235 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
238 }
else if (l2capinbuf[6] == rfcomm_dcid[0] && l2capinbuf[7] == rfcomm_dcid[1]) {
239 rfcommChannel = l2capinbuf[8] & 0xF8;
240 rfcommDirection = l2capinbuf[8] & 0x04;
241 rfcommCommandResponse = l2capinbuf[8] & 0x02;
242 rfcommChannelType = l2capinbuf[9] & 0xEF;
243 rfcommPfBit = l2capinbuf[9] & 0x10;
245 if (rfcommChannel >> 3 != 0x00)
246 rfcommChannelConnection = rfcommChannel;
249 Notify(PSTR(
"\r\nRFCOMM Channel: "), 0x80);
250 D_PrintHex<uint8_t > (rfcommChannel >> 3, 0x80);
251 Notify(PSTR(
" Direction: "), 0x80);
252 D_PrintHex<uint8_t > (rfcommDirection >> 2, 0x80);
253 Notify(PSTR(
" CommandResponse: "), 0x80);
254 D_PrintHex<uint8_t > (rfcommCommandResponse >> 1, 0x80);
255 Notify(PSTR(
" ChannelType: "), 0x80);
256 D_PrintHex<uint8_t > (rfcommChannelType, 0x80);
257 Notify(PSTR(
" PF_BIT: "), 0x80);
258 D_PrintHex<uint8_t > (rfcommPfBit, 0x80);
261 #ifdef DEBUG_USB_HOST
262 Notify(PSTR(
"\r\nReceived Disconnect RFCOMM Command on channel: "), 0x80);
263 D_PrintHex<uint8_t > (rfcommChannel >> 3, 0x80);
266 sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse,
RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00);
270 if (rfcommChannelType ==
RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) {
271 uint8_t length = l2capinbuf[10] >> 1;
272 uint8_t offset = l2capinbuf[4] - length - 4;
273 if (rfcommAvailable + length <=
sizeof (rfcommDataBuffer)) {
274 for (uint8_t i = 0; i < length; i++)
275 rfcommDataBuffer[rfcommAvailable + i] = l2capinbuf[11 + i + offset];
276 rfcommAvailable += length;
279 Notify(PSTR(
"\r\nRFCOMM Data Available: "), 0x80);
280 Notify(rfcommAvailable, 0x80);
282 Notify(PSTR(
" - Credit: 0x"), 0x80);
283 D_PrintHex<uint8_t > (l2capinbuf[11], 0x80);
286 #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth
287 for (uint8_t i = 0; i < length; i++)
288 Notifyc(l2capinbuf[i + 11 + offset], 0x80);
291 #ifdef DEBUG_USB_HOST
292 Notify(PSTR(
"\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
295 rfcommbuf[1] = l2capinbuf[12];
296 rfcommbuf[2] = l2capinbuf[13];
297 rfcommbuf[3] = l2capinbuf[14];
298 rfcommbuf[4] = l2capinbuf[15];
299 rfcommbuf[5] = l2capinbuf[16];
300 rfcommbuf[6] = l2capinbuf[17];
301 rfcommbuf[7] = l2capinbuf[18];
302 rfcommbuf[8] = l2capinbuf[19];
303 rfcommbuf[9] = l2capinbuf[20];
304 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
306 #ifdef DEBUG_USB_HOST
307 Notify(PSTR(
"\r\nSend UIH Modem Status Response"), 0x80);
310 rfcommbuf[1] = 2 << 1 | 1;
311 rfcommbuf[2] = l2capinbuf[13];
312 rfcommbuf[3] = l2capinbuf[14];
313 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
317 #ifdef DEBUG_USB_HOST
318 Notify(PSTR(
"\r\nReceived SABM Command"), 0x80);
320 sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse,
RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00);
322 #ifdef DEBUG_USB_HOST
323 Notify(PSTR(
"\r\nReceived UIH Parameter Negotiation Command"), 0x80);
326 rfcommbuf[1] = l2capinbuf[12];
327 rfcommbuf[2] = l2capinbuf[13];
335 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
337 #ifdef DEBUG_USB_HOST
338 Notify(PSTR(
"\r\nSend UIH Modem Status Response"), 0x80);
341 rfcommbuf[1] = 2 << 1 | 1;
342 rfcommbuf[2] = l2capinbuf[13];
343 rfcommbuf[3] = l2capinbuf[14];
344 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
347 #ifdef DEBUG_USB_HOST
348 Notify(PSTR(
"\r\nSend UIH Modem Status Command"), 0x80);
351 rfcommbuf[1] = 2 << 1 | 1;
352 rfcommbuf[2] = l2capinbuf[13];
355 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
358 #ifdef DEBUG_USB_HOST
359 Notify(PSTR(
"\r\nSend UIH Command with credit"), 0x80);
361 sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0,
RFCOMM_UIH, 0x10,
sizeof (rfcommDataBuffer));
364 waitForLastCommand =
true;
366 }
else if (rfcommChannelType ==
RFCOMM_UIH && l2capinbuf[10] == 0x01) {
367 #ifdef DEBUG_USB_HOST
368 Notify(PSTR(
"\r\nReceived UIH Command with credit"), 0x80);
371 #ifdef DEBUG_USB_HOST
372 Notify(PSTR(
"\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
375 rfcommbuf[1] = l2capinbuf[12];
376 rfcommbuf[2] = l2capinbuf[13];
377 rfcommbuf[3] = l2capinbuf[14];
378 rfcommbuf[4] = l2capinbuf[15];
379 rfcommbuf[5] = l2capinbuf[16];
380 rfcommbuf[6] = l2capinbuf[17];
381 rfcommbuf[7] = l2capinbuf[18];
382 rfcommbuf[8] = l2capinbuf[19];
383 rfcommbuf[9] = l2capinbuf[20];
384 sendRfcomm(rfcommChannel, rfcommDirection, 0,
RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
385 #ifdef DEBUG_USB_HOST
386 Notify(PSTR(
"\r\nRFCOMM Connection is now established\r\n"), 0x80);
388 waitForLastCommand =
false;
393 #ifdef DEBUG_USB_HOST
395 Notify(PSTR(
"\r\nUnsupported RFCOMM Data - ChannelType: "), 0x80);
396 D_PrintHex<uint8_t > (rfcommChannelType, 0x80);
397 Notify(PSTR(
" Command: "), 0x80);
398 D_PrintHex<uint8_t > (l2capinbuf[11], 0x80);
405 Notify(PSTR(
"\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
406 D_PrintHex<uint8_t > (l2capinbuf[7], 0x80);
408 D_PrintHex<uint8_t > (l2capinbuf[6], 0x80);
417 if (waitForLastCommand && (millis() - timer) > 100) {
418 #ifdef DEBUG_USB_HOST
419 Notify(PSTR(
"\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
422 waitForLastCommand =
false;
429 void SPP::SDP_task() {
430 switch (l2cap_sdp_state) {
434 #ifdef DEBUG_USB_HOST
435 Notify(PSTR(
"\r\nSDP Incoming Connection Request"), 0x80);
449 #ifdef DEBUG_USB_HOST
450 Notify(PSTR(
"\r\nSDP Configuration Request"), 0x80);
459 #ifdef DEBUG_USB_HOST
460 Notify(PSTR(
"\r\nSDP Successfully Configured"), 0x80);
470 SDPConnected =
false;
471 #ifdef DEBUG_USB_HOST
472 Notify(PSTR(
"\r\nDisconnected SDP Channel"), 0x80);
481 #ifdef DEBUG_USB_HOST
482 Notify(PSTR(
"\r\nDisconnected L2CAP Connection"), 0x80);
484 RFCOMMConnected =
false;
485 SDPConnected =
false;
488 l2cap_event_flag = 0;
496 void SPP::RFCOMM_task() {
497 switch (l2cap_rfcomm_state) {
501 #ifdef DEBUG_USB_HOST
502 Notify(PSTR(
"\r\nRFCOMM Incoming Connection Request"), 0x80);
516 #ifdef DEBUG_USB_HOST
517 Notify(PSTR(
"\r\nRFCOMM Configuration Request"), 0x80);
526 #ifdef DEBUG_USB_HOST
527 Notify(PSTR(
"\r\nRFCOMM Successfully Configured"), 0x80);
531 RFCOMMConnected =
true;
538 RFCOMMConnected =
false;
540 #ifdef DEBUG_USB_HOST
541 Notify(PSTR(
"\r\nDisconnected RFCOMM Channel"), 0x80);
554 void SPP::SDP_Command(uint8_t* data, uint8_t nbytes) {
555 pBtd->
L2CAP_Command(hci_handle, data, nbytes, sdp_scid[0], sdp_scid[1]);
558 void SPP::serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
560 l2capoutbuf[1] = transactionIDHigh;
561 l2capoutbuf[2] = transactionIDLow;
562 l2capoutbuf[3] = 0x00;
563 l2capoutbuf[4] = 0x05;
564 l2capoutbuf[5] = 0x00;
565 l2capoutbuf[6] = 0x02;
568 l2capoutbuf[7] = 0x35;
569 l2capoutbuf[8] = 0x00;
570 l2capoutbuf[9] = 0x00;
572 SDP_Command(l2capoutbuf, 10);
575 void SPP::serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
577 l2capoutbuf[1] = transactionIDHigh;
578 l2capoutbuf[2] = transactionIDLow;
579 l2capoutbuf[3] = 0x00;
580 l2capoutbuf[4] = 0x2B;
581 l2capoutbuf[5] = 0x00;
582 l2capoutbuf[6] = 0x26;
585 l2capoutbuf[7] = 0x36;
586 l2capoutbuf[8] = 0x00;
587 l2capoutbuf[9] = 0x3C;
588 l2capoutbuf[10] = 0x36;
589 l2capoutbuf[11] = 0x00;
591 l2capoutbuf[12] = 0x39;
592 l2capoutbuf[13] = 0x09;
593 l2capoutbuf[14] = 0x00;
594 l2capoutbuf[15] = 0x00;
595 l2capoutbuf[16] = 0x0A;
596 l2capoutbuf[17] = 0x00;
597 l2capoutbuf[18] = 0x01;
598 l2capoutbuf[19] = 0x00;
599 l2capoutbuf[20] = 0x06;
600 l2capoutbuf[21] = 0x09;
601 l2capoutbuf[22] = 0x00;
602 l2capoutbuf[23] = 0x01;
603 l2capoutbuf[24] = 0x35;
604 l2capoutbuf[25] = 0x03;
605 l2capoutbuf[26] = 0x19;
606 l2capoutbuf[27] = 0x11;
608 l2capoutbuf[28] = 0x01;
609 l2capoutbuf[29] = 0x09;
610 l2capoutbuf[30] = 0x00;
611 l2capoutbuf[31] = 0x04;
612 l2capoutbuf[32] = 0x35;
613 l2capoutbuf[33] = 0x0C;
614 l2capoutbuf[34] = 0x35;
615 l2capoutbuf[35] = 0x03;
616 l2capoutbuf[36] = 0x19;
617 l2capoutbuf[37] = 0x01;
618 l2capoutbuf[38] = 0x00;
619 l2capoutbuf[39] = 0x35;
620 l2capoutbuf[40] = 0x05;
621 l2capoutbuf[41] = 0x19;
622 l2capoutbuf[42] = 0x00;
623 l2capoutbuf[43] = 0x03;
625 l2capoutbuf[44] = 0x08;
626 l2capoutbuf[45] = 0x02;
627 l2capoutbuf[46] = 0x00;
628 l2capoutbuf[47] = 0x19;
630 SDP_Command(l2capoutbuf, 48);
633 void SPP::serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
635 l2capoutbuf[1] = transactionIDHigh;
636 l2capoutbuf[2] = transactionIDLow;
637 l2capoutbuf[3] = 0x00;
638 l2capoutbuf[4] = 0x1C;
639 l2capoutbuf[5] = 0x00;
640 l2capoutbuf[6] = 0x19;
643 l2capoutbuf[7] = 0x01;
644 l2capoutbuf[8] = 0x09;
645 l2capoutbuf[9] = 0x00;
646 l2capoutbuf[10] = 0x06;
647 l2capoutbuf[11] = 0x35;
649 l2capoutbuf[12] = 0x09;
650 l2capoutbuf[13] = 0x09;
651 l2capoutbuf[14] = 0x65;
652 l2capoutbuf[15] = 0x6E;
653 l2capoutbuf[16] = 0x09;
654 l2capoutbuf[17] = 0x00;
655 l2capoutbuf[18] = 0x6A;
656 l2capoutbuf[19] = 0x09;
657 l2capoutbuf[20] = 0x01;
658 l2capoutbuf[21] = 0x00;
659 l2capoutbuf[22] = 0x09;
660 l2capoutbuf[23] = 0x01;
661 l2capoutbuf[24] = 0x00;
662 l2capoutbuf[25] = 0x25;
664 l2capoutbuf[26] = 0x05;
665 l2capoutbuf[27] =
'T';
666 l2capoutbuf[28] =
'K';
667 l2capoutbuf[29] =
'J';
668 l2capoutbuf[30] =
'S';
669 l2capoutbuf[31] =
'P';
670 l2capoutbuf[32] = 0x00;
672 SDP_Command(l2capoutbuf, 33);
675 void SPP::l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
676 serialPortResponse1(transactionIDHigh, transactionIDLow);
679 void SPP::l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
680 serialPortResponse2(transactionIDHigh, transactionIDLow);
686 void SPP::RFCOMM_Command(uint8_t* data, uint8_t nbytes) {
687 pBtd->
L2CAP_Command(hci_handle, data, nbytes, rfcomm_scid[0], rfcomm_scid[1]);
690 void SPP::sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length) {
692 l2capoutbuf[1] = channelType | pfBit;
693 l2capoutbuf[2] = length << 1 | 0x01;
695 for (; i < length; i++)
696 l2capoutbuf[i + 3] = data[i];
697 l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
699 Notify(PSTR(
" - RFCOMM Data: "), 0x80);
700 for (i = 0; i < length + 4; i++) {
701 D_PrintHex<uint8_t > (l2capoutbuf[i], 0x80);
705 RFCOMM_Command(l2capoutbuf, length + 4);
708 void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit) {
710 l2capoutbuf[1] = channelType | pfBit;
711 l2capoutbuf[2] = 0x01;
712 l2capoutbuf[3] = credit;
713 l2capoutbuf[4] = calcFcs(l2capoutbuf);
715 Notify(PSTR(
" - RFCOMM Credit Data: "), 0x80);
716 for (uint8_t i = 0; i < 5; i++) {
717 D_PrintHex<uint8_t > (l2capoutbuf[i], 0x80);
721 RFCOMM_Command(l2capoutbuf, 5);
725 uint8_t SPP::__crc(uint8_t* data) {
730 uint8_t SPP::calcFcs(uint8_t *data) {
732 return (0xff - __crc(data));
739 return write(&data,1);
743 for(uint8_t i = 0; i < size; i++) {
744 if(sppIndex >=
sizeof(sppOutputBuffer)/
sizeof(sppOutputBuffer[0]))
746 sppOutputBuffer[sppIndex++] = data[i];
757 l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 |
extendAddress;
761 if (sppIndex > (
sizeof (l2capoutbuf) - 4))
762 length =
sizeof (l2capoutbuf) - 4;
766 l2capoutbuf[2] = length << 1 | 1;
768 for (; i < length; i++)
769 l2capoutbuf[i + 3] = sppOutputBuffer[i + offset];
770 l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
772 RFCOMM_Command(l2capoutbuf, length + 4);
780 return rfcommAvailable;
788 if (rfcommAvailable == 0)
790 return rfcommDataBuffer[0];
794 if (rfcommAvailable == 0)
796 uint8_t output = rfcommDataBuffer[0];
797 for (uint8_t i = 1; i < rfcommAvailable; i++)
798 rfcommDataBuffer[i - 1] = rfcommDataBuffer[i];
801 if (bytesRead > (
sizeof (rfcommDataBuffer) - 5)) {
803 sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0,
RFCOMM_UIH, 0x10,
sizeof (rfcommDataBuffer));
805 Notify(PSTR(
"\r\nSent "), 0x80);
806 Notify((uint8_t)
sizeof (rfcommDataBuffer), 0x80);
807 Notify(PSTR(
" more credit"), 0x80);