diff --git a/example/Makefile.am b/example/Makefile.am index 990ca0ac8..ba6198122 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1,5 +1,10 @@ -bin_PROGRAMS = test -test_SOURCES = test.c ../src/btstack.c ../src/utils.c ../src/hci.c \ - ../src/l2cap.c ../src/linked_list.c ../src/run_loop.c \ - ../src/hci_dump.c ../src/hci_cmds.c ../src/socket_connection.c - +bin_PROGRAMS = test +test_SOURCES = test.c \ + ../src/btstack.c \ + ../src/l2cap_signaling.c \ + ../src/hci_cmds.c \ + ../src/hci_dump.c \ + ../src/linked_list.c \ + ../src/run_loop.c \ + ../src/socket_connection.c \ + ../src/utils.c diff --git a/project.xcodeproj/project.pbxproj b/project.xcodeproj/project.pbxproj index 615a76af1..987d42d95 100644 --- a/project.xcodeproj/project.pbxproj +++ b/project.xcodeproj/project.pbxproj @@ -12,6 +12,8 @@ 9C00F7D81019082F008DAB17 /* hci_cmds.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F7D61019082F008DAB17 /* hci_cmds.c */; }; 9C00F86410191097008DAB17 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F86210191097008DAB17 /* utils.c */; }; 9C00F86510191097008DAB17 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F86210191097008DAB17 /* utils.c */; }; + 9C00F87310191130008DAB17 /* l2cap_signaling.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F87210191130008DAB17 /* l2cap_signaling.c */; }; + 9C00F87410191130008DAB17 /* l2cap_signaling.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F87210191130008DAB17 /* l2cap_signaling.c */; }; 9C1F0E9A0FDAE023008F472F /* run_loop.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C1F0E980FDAE023008F472F /* run_loop.c */; }; 9C2071F310014D3200A07EA4 /* hci_transport_usb.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */; }; 9C20720F10025E0500A07EA4 /* libusb-1.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C20720E10025E0500A07EA4 /* libusb-1.0.dylib */; }; @@ -53,6 +55,8 @@ 9C00F7D61019082F008DAB17 /* hci_cmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hci_cmds.c; path = src/hci_cmds.c; sourceTree = ""; }; 9C00F86210191097008DAB17 /* utils.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = utils.c; path = src/utils.c; sourceTree = ""; }; 9C00F86310191097008DAB17 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = utils.h; path = src/utils.h; sourceTree = ""; }; + 9C00F87110191130008DAB17 /* l2cap_signaling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = l2cap_signaling.h; path = src/l2cap_signaling.h; sourceTree = ""; }; + 9C00F87210191130008DAB17 /* l2cap_signaling.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = l2cap_signaling.c; path = src/l2cap_signaling.c; sourceTree = ""; }; 9C1F0E980FDAE023008F472F /* run_loop.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = run_loop.c; path = src/run_loop.c; sourceTree = ""; }; 9C1F0E990FDAE023008F472F /* run_loop.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = run_loop.h; path = src/run_loop.h; sourceTree = ""; }; 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hci_transport_usb.c; path = src/hci_transport_usb.c; sourceTree = ""; }; @@ -136,6 +140,8 @@ 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */, 9C88500C0FBF6702004980E4 /* l2cap.c */, 9C88500D0FBF6702004980E4 /* l2cap.h */, + 9C00F87110191130008DAB17 /* l2cap_signaling.h */, + 9C00F87210191130008DAB17 /* l2cap_signaling.c */, 9C7B5ABE100BD3340065D87E /* linked_list.h */, 9C7B5ABF100BD3340065D87E /* linked_list.c */, 9C1F0E990FDAE023008F472F /* run_loop.h */, @@ -246,6 +252,7 @@ 9C00F7321017ACC3008DAB17 /* socket_connection.c in Sources */, 9C00F7D71019082F008DAB17 /* hci_cmds.c in Sources */, 9C00F86510191097008DAB17 /* utils.c in Sources */, + 9C00F87410191130008DAB17 /* l2cap_signaling.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -263,6 +270,7 @@ 9C7B5D12100FC9F00065D87E /* l2cap.c in Sources */, 9C00F7D81019082F008DAB17 /* hci_cmds.c in Sources */, 9C00F86410191097008DAB17 /* utils.c in Sources */, + 9C00F87310191130008DAB17 /* l2cap_signaling.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/Makefile.am b/src/Makefile.am index 309b9fa2b..5dd34552e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,7 @@ BTdaemon_SOURCES = \ hci_transport_h4.c \ $(usb_support) \ l2cap.c \ + l2cap_signaling.c \ linked_list.c \ run_loop.c \ socket_connection.c \ @@ -29,6 +30,7 @@ include_HEADERS = \ hci_transport_usb.h \ linked_list.h \ l2cap.h \ + l2cap_signaling.h \ run_loop.h \ socket_connection.h \ utils.h diff --git a/src/l2cap.c b/src/l2cap.c index 2cab3f1f6..22f8b14f6 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -13,77 +13,8 @@ #include -static char *l2cap_signaling_commands_format[] = { - "D", // 0x01 command reject: reason {cmd not understood (0), sig MTU exceeded (2:max sig MTU), invalid CID (4:req CID)}, data len, data - "22", // 0x02 connection request: PSM, Source CID - "2222", // 0x03 connection response: Dest CID, Source CID, Result, Status - "22D", // 0x04 config request: Dest CID, Flags, Configuration options - "222D", // 0x05 config response: Source CID, Flags, Result, Configuration options - "22", // 0x06 disconection request: Dest CID, Source CID - "22", // 0x07 disconection response: Dest CID, Source CID - "D", // 0x08 echo request: Data - "D", // 0x09 echo response: Data - "2", // 0x0a information request: InfoType {1=Connectionless MTU, 2=Extended features supported} - "22D", // 0x0b information response: InfoType, Result, Data -}; - static uint8_t * sig_buffer; -uint8_t sig_seq_nr = 1; -uint16_t local_cid = 0x40; - -uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer,hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr){ - - // 0 - Connection handle : PB=10 : BC=00 - bt_store_16(acl_buffer, 0, handle | (2 << 12) | (0 << 14)); - // 6 - L2CAP channel = 1 - bt_store_16(acl_buffer, 6, 1); - // 8 - Code - acl_buffer[8] = cmd; - // 9 - id (!= 0 sequentially) - acl_buffer[9] = identifier; - - // 12 - L2CAP signaling parameters - uint16_t pos = 12; - const char *format = l2cap_signaling_commands_format[cmd-1]; - uint16_t word; - uint8_t * ptr; - while (*format) { - switch(*format) { - case '1': // 8 bit value - case '2': // 16 bit value - word = va_arg(argptr, int); - // minimal va_arg is int: 2 bytes on 8+16 bit CPUs - acl_buffer[pos++] = word & 0xff; - if (*format == '2') { - acl_buffer[pos++] = word >> 8; - } - break; - case 'D': // variable data. passed: len, ptr - word = va_arg(argptr, int); - ptr = va_arg(argptr, uint8_t *); - memcpy(&acl_buffer[pos], ptr, word); - pos += word; - break; - default: - break; - } - format++; - }; - va_end(argptr); - - // Fill in various length fields: it's the number of bytes following for ACL lenght and l2cap parameter length - // - the l2cap payload length is counted after the following channel id (only payload) - - // 2 - ACL length - bt_store_16(acl_buffer, 2, pos - 4); - // 4 - L2CAP packet length - bt_store_16(acl_buffer, 4, pos - 6 - 2); - // 10 - L2CAP signaling parameter length - bt_store_16(acl_buffer, 10, pos - 12); - - return pos; -} int l2cap_send_signaling_packet(hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, ...){ va_list argptr; va_start(argptr, identifier); diff --git a/src/l2cap.h b/src/l2cap.h index 15094270c..4f5592412 100644 --- a/src/l2cap.h +++ b/src/l2cap.h @@ -9,20 +9,7 @@ #pragma once #include "hci.h" - -typedef enum { - COMMAND_REJECT = 1, - CONNECTION_REQUEST, - CONNECTION_RESPONSE, - CONFIGURE_REQUEST, - CONFIGURE_RESPONSE, - DISCONNECTION_REQUEST, - DISCONNECTION_RESPONSE, - ECHO_REQUEST, - ECHO_RESPONSE, - INFORMATIONAL_REQUEST, - INFORMATIONAL_RESPONSE -} L2CAP_SIGNALING_COMMANDS; +#include "l2cap_signaling.h" typedef struct { @@ -33,9 +20,4 @@ typedef struct { } l2cap_service_t; void l2cap_init(); -uint16_t l2cap_create_signaling_packet(uint8_t *acl_buffer, hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, ...); -uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer,hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr); int l2cap_send_signaling_packet(hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, ...); - -extern uint16_t local_cid; -extern uint8_t sig_seq_nr; diff --git a/src/l2cap_signaling.c b/src/l2cap_signaling.c new file mode 100644 index 000000000..b222d8ca0 --- /dev/null +++ b/src/l2cap_signaling.c @@ -0,0 +1,79 @@ +/* + * l2cap_signaling.h + * + * Created by Matthias Ringwald on 7/23/09. + */ + +#include "l2cap_signaling.h" + +#include + +static char *l2cap_signaling_commands_format[] = { +"D", // 0x01 command reject: reason {cmd not understood (0), sig MTU exceeded (2:max sig MTU), invalid CID (4:req CID)}, data len, data +"22", // 0x02 connection request: PSM, Source CID +"2222", // 0x03 connection response: Dest CID, Source CID, Result, Status +"22D", // 0x04 config request: Dest CID, Flags, Configuration options +"222D", // 0x05 config response: Source CID, Flags, Result, Configuration options +"22", // 0x06 disconection request: Dest CID, Source CID +"22", // 0x07 disconection response: Dest CID, Source CID +"D", // 0x08 echo request: Data +"D", // 0x09 echo response: Data +"2", // 0x0a information request: InfoType {1=Connectionless MTU, 2=Extended features supported} +"22D", // 0x0b information response: InfoType, Result, Data +}; + +uint8_t sig_seq_nr = 1; +uint16_t local_cid = 0x40; + +uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer,hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr){ + + // 0 - Connection handle : PB=10 : BC=00 + bt_store_16(acl_buffer, 0, handle | (2 << 12) | (0 << 14)); + // 6 - L2CAP channel = 1 + bt_store_16(acl_buffer, 6, 1); + // 8 - Code + acl_buffer[8] = cmd; + // 9 - id (!= 0 sequentially) + acl_buffer[9] = identifier; + + // 12 - L2CAP signaling parameters + uint16_t pos = 12; + const char *format = l2cap_signaling_commands_format[cmd-1]; + uint16_t word; + uint8_t * ptr; + while (*format) { + switch(*format) { + case '1': // 8 bit value + case '2': // 16 bit value + word = va_arg(argptr, int); + // minimal va_arg is int: 2 bytes on 8+16 bit CPUs + acl_buffer[pos++] = word & 0xff; + if (*format == '2') { + acl_buffer[pos++] = word >> 8; + } + break; + case 'D': // variable data. passed: len, ptr + word = va_arg(argptr, int); + ptr = va_arg(argptr, uint8_t *); + memcpy(&acl_buffer[pos], ptr, word); + pos += word; + break; + default: + break; + } + format++; + }; + va_end(argptr); + + // Fill in various length fields: it's the number of bytes following for ACL lenght and l2cap parameter length + // - the l2cap payload length is counted after the following channel id (only payload) + + // 2 - ACL length + bt_store_16(acl_buffer, 2, pos - 4); + // 4 - L2CAP packet length + bt_store_16(acl_buffer, 4, pos - 6 - 2); + // 10 - L2CAP signaling parameter length + bt_store_16(acl_buffer, 10, pos - 12); + + return pos; +} diff --git a/src/l2cap_signaling.h b/src/l2cap_signaling.h new file mode 100644 index 000000000..6703a816d --- /dev/null +++ b/src/l2cap_signaling.h @@ -0,0 +1,31 @@ +/* + * l2cap_signaling.h + * + * Created by Matthias Ringwald on 7/23/09. + */ + +#pragma once + +#include +#include "utils.h" +#include "hci_cmds.h" + +typedef enum { + COMMAND_REJECT = 1, + CONNECTION_REQUEST, + CONNECTION_RESPONSE, + CONFIGURE_REQUEST, + CONFIGURE_RESPONSE, + DISCONNECTION_REQUEST, + DISCONNECTION_RESPONSE, + ECHO_REQUEST, + ECHO_RESPONSE, + INFORMATIONAL_REQUEST, + INFORMATIONAL_RESPONSE +} L2CAP_SIGNALING_COMMANDS; + +extern uint16_t local_cid; +extern uint8_t sig_seq_nr; + +uint16_t l2cap_create_signaling_packet(uint8_t *acl_buffer, hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, ...); +uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer,hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr);