diff --git a/docs/manual/markdown/Makefile b/docs/manual/markdown/Makefile index 48f63b2c9..4ee5d7fe9 100644 --- a/docs/manual/markdown/Makefile +++ b/docs/manual/markdown/Makefile @@ -1,15 +1,20 @@ all: ./update_apis.py ./update_listings.py + rm -rf docs_tmp + rm -rf docs_final + cp -r docs docs_tmp + cp -r docs docs_final + ./markdown2mkdocs.py + rm -rf docs_tmp mkdocs build --clean - echo "a.toctree-l4 { display: none; }" >> btstack/css/theme_extra.css mkdir -p latex cp -r docs/picts latex cp ../picts/bklogo.pdf latex/picts ./markdown2pdf.py cp btstack_gettingstarted.tex latex cd latex && pdflatex btstack_gettingstarted.tex && pdflatex btstack_gettingstarted.tex - mv latex/btstack_gettingstarted.pdf btstack + mv latex/btstack_gettingstarted.pdf btstack.pdf rm -rf latex diff --git a/docs/manual/markdown/btstack_gettingstarted.tex b/docs/manual/markdown/btstack_gettingstarted.tex index 0127bb943..db9ce215c 100644 --- a/docs/manual/markdown/btstack_gettingstarted.tex +++ b/docs/manual/markdown/btstack_gettingstarted.tex @@ -1,6 +1,6 @@ \documentclass[a4paper,titlepage,oneside,12pt]{amsart} %amsart \usepackage{graphicx} -\usepackage{hyperref} +\usepackage[colorlinks=true]{hyperref} %\usepackage{geometry} % see geometry.pdf on how to lay out the page. There's lots. \usepackage[margin=1.3in]{geometry} \geometry{a4paper} % or letter or a5paper or ... etc @@ -147,6 +147,9 @@ morekeywords={*, timer_source_t, data_source_t, uint32_t, uint16_t, uint8_t, RUN \begin{document} \maketitle +\hypersetup{linkcolor=blue} +\hypersetup{urlcolor=blue} +\hypersetup{citecolor=blue} \tableofcontents \pagebreak diff --git a/docs/manual/markdown/docs/appendix/events_errors.md b/docs/manual/markdown/docs/appendix/events_errors.md index b52854269..3eafa0ba3 100644 --- a/docs/manual/markdown/docs/appendix/events_errors.md +++ b/docs/manual/markdown/docs/appendix/events_errors.md @@ -1,6 +1,5 @@ -## L2CAP Events -<a name="appendix:events_and_errors"></a> +## L2CAP Events {#sec:eventsAndErrorsAppendix} L2CAP events and data packets are delivered to the packet handler specified by *l2cap_register_service* resp. diff --git a/docs/manual/markdown/docs/architecture.md b/docs/manual/markdown/docs/architecture.md index 9eabd4a02..537ba8e81 100644 --- a/docs/manual/markdown/docs/architecture.md +++ b/docs/manual/markdown/docs/architecture.md @@ -42,7 +42,7 @@ events. During a run loop cycle, the callback functions of all registered data sources are called. Then, the callback functions of timers that are ready are executed. -For adapting BTstack to multi-threaded environments check [here](integration/#adapting-btstack-for-multi-threaded-environments). +For adapting BTstack to multi-threaded environments check [here](integration/#sec:multithreadingIntegration). ## No blocking anywhere diff --git a/docs/manual/markdown/docs/how_to.md b/docs/manual/markdown/docs/how_to.md index 3098944c7..84a90ea0b 100644 --- a/docs/manual/markdown/docs/how_to.md +++ b/docs/manual/markdown/docs/how_to.md @@ -12,9 +12,7 @@ an overview is provided here. Finally, we describe the RFCOMM credit-based flow-control, which may be necessary for resource-constraint devices. -<a name ="section:memory_configuration"></a> - -## Memory configuration +## Memory configuration {#sec:memoryConfigurationHowTo} The structs for services, active connections and remote devices can be allocated in two different manners: @@ -53,9 +51,8 @@ The memory is set up by calling *btstack_memory_init* function: btstack_memory_init(); -<a name"section:run_loop"></a> -## Run loop +## Run loop {#sec:runLoopHowTo} BTstack uses a run loop to handle incoming data and to schedule work. The run loop handles events from two different types of sources: data @@ -91,7 +88,8 @@ before its event handler callback is executed. If you need a periodic timer, you can re-register the same timer source in the callback function, as shown in Listing [PeriodicTimerHandler]. Note that BTstack expects to get called periodically to keep its time, see Section -[on time abstraction](#section:test) for more on the tick hardware abstraction. +[on time abstraction](#sec:timeAbstractionPorting) for more on the +tick hardware abstraction. The run loop is set up by calling *run_loop_init* function for embedded systems: @@ -100,7 +98,7 @@ embedded systems: run_loop_init(RUN_LOOP_EMBEDDED); -The Run loop API is provided [here](appendix/apis/#appendix:api_run_loop). To +The Run loop API is provided [here](appendix/apis/#sec:runLoopAPIAppendix). To enable the use of timers, make sure that you defined HAVE_TICK in the config file. @@ -109,12 +107,11 @@ as shown in Listing [listing:btstackInit]. The application can register data sources as well as timers, e.g., periodical sampling of sensors, or communication over the UART. -<a nam="sec:btstack_initialization"></a> -## BTstack initialization {#section:test} +## BTstack initialization {#sec:btstackInitializationHowTo} -To initialize BTstack you need to [initialize the memory](#section:memory_configuration) -and [the run loop](#section:run_loop) respectively, then setup HCI and all needed higher +To initialize BTstack you need to [initialize the memory](#sec:memoryConfigurationHowTo) +and [the run loop](#sec:runLoopHowTo) respectively, then setup HCI and all needed higher level protocols. The HCI initialization has to adapt BTstack to the used platform and @@ -146,7 +143,7 @@ requires four arguments. These are: [src/hci_transport_h4_dma.c]() resp. [src/hci_transport_h4_ehcill_dma.c]() and then getting a pointer to HCI Transport implementation. For more information on adapting HCI Transport to different - environments, see [here](porting/#hci-transport-implementation). + environments, see [here](porting/#sec:hciTransportPorting). <!-- --> @@ -173,7 +170,7 @@ requires four arguments. These are: keys or remote device names. This commonly requires platform specific code to access the MCU’s EEPROM of Flash storage. For the first steps, BTstack provides a (non) persistent store in memory. - For more see [here](porting/#persistent-storage-api). + For more see [here](porting/#sec:persistentStoragePorting). <!-- --> @@ -190,9 +187,8 @@ themselves with the underlying layer. In addition, the application can register packet handlers to get events and data as explained in the following section. -<a name="sec:services"></a> -## Services +## Services {#sec:servicesHowTo} One important construct of BTstack is *service*. A service represents a server side component that handles incoming connections. So far, BTstack @@ -204,9 +200,8 @@ ID. Outgoing connections require no special registration, they are created by the application when needed. -<a name="sec:packetHandlers"></a> -## Where to get data - packet handlers +## Where to get data - packet handlers {#sec:packetHandlersHowTo} After the hardware and BTstack are set up, the run loop is entered. From @@ -216,7 +211,7 @@ resulting events are delivered back to the application. Instead of writing a single callback handler for each possible event (as it is done in some other Bluetooth stacks), BTstack groups events logically and provides them over a single generic interface. Appendix -[Events and Errors](generated/appendix/#events_and_errors) +[Events and Errors](generated/appendix/#sec:eventsAndErrorsAppendix) summarizes the parameters and event codes of L2CAP and RFCOMM events, as well as possible errors and the corresponding error codes. @@ -282,9 +277,8 @@ services for the HID Control and HID Interrupt PSMs using a packet handler to accept and receive keyboard data. -<a name="sec:packetlogs"></a> -## Bluetooth HCI Packet Logs +## Bluetooth HCI Packet Logs {#sec:packetlogsHowTo} If things don't work as expected, having a look at the data exchanged diff --git a/docs/manual/markdown/docs/index.md b/docs/manual/markdown/docs/index.md index adfdea24a..0d3d4b9ec 100644 --- a/docs/manual/markdown/docs/index.md +++ b/docs/manual/markdown/docs/index.md @@ -8,5 +8,6 @@ protocols and profiles. A series of examples show how BTstack can be used to implement common use cases. -Finally, we outline the basic steps when integrating BTstack into existing single-threaded or even multi-threaded environments. The changes in the documentation are listed in the [Revision History](revision_history). +Finally, we outline the basic steps when integrating BTstack into existing +single-threaded or even multi-threaded environments. diff --git a/docs/manual/markdown/docs/integration.md b/docs/manual/markdown/docs/integration.md index 8ae7dd494..a3a799f88 100644 --- a/docs/manual/markdown/docs/integration.md +++ b/docs/manual/markdown/docs/integration.md @@ -11,9 +11,8 @@ contains the packet handler (PH) that handles all asynchronous events and data packets from BTstack. The Main Application makes use of the Communication Logic for its Bluetooth communication. -<a name="sec:singlethreading"></a> -## Adapting BTstack for Single-Threaded Environments +## Adapting BTstack for Single-Threaded Environments {#sec:singlethreadingIntegration} In a single-threaded environment, all application components run on the @@ -41,9 +40,8 @@ Currently, we have two examples for this: managed in a linked list. Then, the*select* function is used to wait for the next file descriptor to become ready or timer to expire. -<a name="sec:multithreading"></a> -## Adapting BTstack for Multi-Threaded Environments +## Adapting BTstack for Multi-Threaded Environments {#sec:multithreadingIntegration} The basic execution model of BTstack is a general while loop. Aside from diff --git a/docs/manual/markdown/docs/porting.md b/docs/manual/markdown/docs/porting.md index d7c68816f..e6ec7fad8 100644 --- a/docs/manual/markdown/docs/porting.md +++ b/docs/manual/markdown/docs/porting.md @@ -1,9 +1,8 @@ In this section, we highlight the BTstack components that need to be adjusted for different hardware platforms. -<a name="section:timeAbstraction"></a> -## Time Abstraction Layer +## Time Abstraction Layer {#sec:timeAbstractionPorting} BTstack requires a way to learn about passing time. *run_loop_embedded.c* supports two different modes: system ticks or a @@ -12,7 +11,7 @@ are quite low as only Bluetooth timeouts in the second range need to be handled. -### Tick Hardware Abstraction ### {#section:tickAbstraction} +### Tick Hardware Abstraction {#sec:tickAbstractionPorting} If your platform doesn’t require a system clock or if you already have a @@ -37,9 +36,8 @@ After BTstack calls *hal_tick_init()* and *tick_handler* gets called every *hal_tick_get_tick_period_in_ms()* ms. -<a name="sec:timeMSAbstraction"></a> -### Time MS Hardware Abstraction +### Time MS Hardware Abstraction {#sec:timeMSAbstractionPorting} If your platform already has a system clock or it is more convenient to @@ -57,9 +55,7 @@ future. It has to return the time in milliseconds. uint32_t hal_time_ms(void); -<a name="sec:bt_hw_control"></a> - -## Bluetooth Hardware Control API +## Bluetooth Hardware Control API {#sec:btHWControlPorting} The Bluetooth hardware control API can provide the HCI layer with a @@ -76,9 +72,8 @@ that is not covered by the Bluetooth specification. As an example, the struct suitable for the CC256x chipset. -<a name="sec:hci_transport"></a> -## HCI Transport Implementation +## HCI Transport Implementation {#sec:hciTransportPorting} On embedded systems, a Bluetooth module can be connected via USB or an @@ -87,9 +82,8 @@ commands, events and data between a host and a Bluetooth module: HCI UART Transport Layer (H4) and H4 with eHCILL support, a lightweight low-power variant by Texas Instruments. -<a name="sec:hciUART"></a> -### HCI UART Transport Layer (H4) +### HCI UART Transport Layer (H4) {#sec:hciUARTPorting} Most embedded UART interfaces operate on the byte level and generate a @@ -142,9 +136,8 @@ callback for CTS interrupts. void hal_uart_dma_set_cts_irq_handler(void(*cts_irq_handler)(void)); void hal_uart_dma_set_sleep(uint8_t sleep); -<a name="sec:persistent_storage"></a> -## Persistent Storage API +## Persistent Storage API {#sec:persistentStoragePorting} On embedded systems there is no generic way to persist data like link keys or remote device names, as every type of a device has its own diff --git a/docs/manual/markdown/docs/profiles.md b/docs/manual/markdown/docs/profiles.md index c699af38a..53aa0e949 100644 --- a/docs/manual/markdown/docs/profiles.md +++ b/docs/manual/markdown/docs/profiles.md @@ -43,10 +43,15 @@ undiscoverable again, once a connection is established. See Listing ### Discover remote devices {#section:DiscoverRemoteDevices} To scan for remote devices, the *hci_inquiry* command is used. Found -remote devices are reported as a part of HCI_EVENT_INQUIRY_RESULT, -HCI_EVENT-_INQUIRY_RESULT_WITH_RSSI, or -HCI_EVENT_EXTENDED_INQUIRY_RESPONSE events. Each response contains -at least the Bluetooth address, the class of device, the page scan +remote devices are reported as a part of: + +- HCI_EVENT_INQUIRY_RESULT, + +- HCI_EVENT-_INQUIRY_RESULT_WITH_RSSI, or + +- HCI_EVENT_EXTENDED_INQUIRY_RESPONSE events. + +Each response contains at least the Bluetooth address, the class of device, the page scan repetition mode, and the clock offset of found device. The latter events add information about the received signal strength or provide the Extended Inquiry Result (EIR). A code snippet is shown in Listing @@ -104,7 +109,7 @@ device implements Bluetooth Specification 2.1 or higher, the *hci_write_inquiry_mode* command enables reporting of this advanced features (0 for standard results, 1 for RSSI, 2 for RSSI and EIR). -A complete GAP inquiry example is provided [here](examples/#gapinquiry). +A complete GAP inquiry example is provided [here](examples/generated/#sec:gapinquiryExample). ### Pairing of Devices @@ -150,8 +155,8 @@ user. Regardless of the authentication mechanism (PIN/SSP), on success, both devices will generate a link key. The link key can be stored either in -the Bluetooth module itself or in a persistent storage, see [here](#examples/#persistent_storage). -The next time the device connects and +the Bluetooth module itself or in a persistent storage, see +[here](porting/#sec:persistentStoragePorting). The next time the device connects and requests an authenticated connection, both devices can use the previously generated link key. Please note that the pairing must be repeated if the link key is lost by one device. @@ -177,22 +182,21 @@ for its SPP services. Section [subsection:querysdp] shows how to query for all RFCOMM channels. For SPP, you can do the same but use the SPP UUID 0x1101 for the query. After you have identified the correct RFCOMM channel, you can create an RFCOMM connection as shown -[here](protocols/#sec:rfcommlient). +[here](protocols/#sec:rfcommClientProtocols). ### Providing an SPP Server To provide an SPP Server, you need to provide an RFCOMM service with a specific RFCOMM channel number as explained in section on -[RFCOMM service](protocols/#sec:rfcomm_service). Then, you need to create +[RFCOMM service](protocols/#sec:rfcommServiceProtocols). Then, you need to create an SDP record for it and publish it with the SDP server by calling *sdp_register_service_internal*. BTstack provides the *sdp_create_spp_service* function in that requires an empty buffer of approximately 200 bytes, the service channel number, and a service name. -Have a look at the [SPP Counter example](examples/generated/#section:sppcounter]. +Have a look at the [SPP Counter example](examples/generated/#sec:sppcounterExample]. -<a name="section:pan_profile"></a> -## PAN - Personal Area Networking Profile +## PAN - Personal Area Networking Profile {#sec:panProfiles} The PAN profile uses BNEP to provide on-demand networking capabilities @@ -234,7 +238,7 @@ information, you can connect BNEP to the remote PANU service with the To provide a PANU service, you need to provide a BNEP service with the service UUID, e.g. the PANU UUID, and a a maximal ethernet frame size, -as explained in Section [subsubsection:bnepserver]. Then, you need to +as explained in Section [on BNEP service](protocols/#sec:bnepServiceProtocols). Then, you need to create an SDP record for it and publish it with the SDP server by calling *sdp_register_service_internal*. BTstack provides the *pan_create_panu_service* function in *src/pan.c* that requires an @@ -266,8 +270,8 @@ To toggle privacy mode using private addresses, call the with *gap_random_address_set_update_period*. After a connection is established, the Security Manager will try to -resolve the peer Bluetooth address as explained in Section -[section:smp]. +resolve the peer Bluetooth address as explained in Section on +[SMP](protocols/#sec:smpProtocols). ### Advertising and Discovery @@ -283,8 +287,8 @@ commands can be used: - *hci_le_set_advertise_enable* As these are direct HCI commands, please refer to Section -[subsubsection:sendinghci] for details and have a look at the SPP and LE -Counter example in Section [example:sppandlecounter]. +[subsubsection:sendinghci] for details and have a look at the [SPP and LE +Counter example](examples/generated/#sec:sppandlecounterExample). In addition to the Advertisement data, a device in the peripheral role can also provide Scan Response data, which has to be explicitly queried @@ -317,9 +321,8 @@ Services are queried and modified via ATT operations. GATT defines both a server and a client role. A device can implement one or both GATT roles. -<a name = "section:GATTClient"></a> -### GATT Client +### GATT Client {#sec:GATTClientProfiles} The GATT Client is used to discover services, and their characteristics and descriptors on a peer device. It can also subscribe for @@ -347,11 +350,10 @@ perform a GATT query on a particular connection using completes the query. For more details on the available GATT queries, please consult -[GATT Client API](#appendix:api_gatt_client). +[GATT Client API](#sec:gattClientAPIAppendix). -<a name="section:GATTServer"></a> -### GATT Server +### GATT Server {#sec:GATTServerProfiles} The GATT server stores data and accepts GATT client requests, commands and confirmations. The GATT server sends responses to requests and when diff --git a/docs/manual/markdown/docs/protocols.md b/docs/manual/markdown/docs/protocols.md index d48ba21e0..c887f5330 100644 --- a/docs/manual/markdown/docs/protocols.md +++ b/docs/manual/markdown/docs/protocols.md @@ -137,8 +137,8 @@ and info on their parameters. S Service Record (Data Element Sequence) ------------------- ---------------------------------------------------- -### Sending HCI command based on a template -<a name ="sec:sendinghci"></a> + +### Sending HCI command based on a template {#sec:sendingHCIProtocols} You can use the *hci_send_cmd* function to send HCI command based on a template and a list of parameters. However, it is necessary to check @@ -163,8 +163,9 @@ Please note, that an application rarely has to send HCI commands on its own. Instead, BTstack provides convenience functions in GAP and higher level protocols use HCI automatically. -L2CAP - Logical Link Control and Adaptation Protocol ----------------------------------------------------- + +## L2CAP - Logical Link Control and Adaptation Protocol + The L2CAP protocol supports higher level protocol multiplexing and packet fragmentation. It provides the base for the RFCOMM and BNEP @@ -185,7 +186,7 @@ To communicate with an L2CAP service on a remote device, the application on a local Bluetooth device initiates the L2CAP layer using the *l2cap_init* function, and then creates an outgoing L2CAP channel to the PSM of a remote device using the *l2cap_create_channel_internal* -function. The *l2cap_-create_channel_internal* function will initiate +function. The *l2cap_create_channel_internal* function will initiate a new baseband connection if it does not already exist. The packet handler that is given as an input parameter of the L2CAP create channel function will be assigned to the new outgoing L2CAP channel. This @@ -298,8 +299,8 @@ BTstack provides an optimized *l2cap_le* implementation in the *ble* folder. This L2CAP LE variant can be used for single-mode devices and provides the base for the ATT and SMP protocols. -RFCOMM - Radio Frequency Communication Protocol ------------------------------------------------ + +## RFCOMM - Radio Frequency Communication Protocol The Radio frequency communication (RFCOMM) protocol provides emulation of serial ports over the L2CAP protocol. and reassembly. It is the base @@ -307,8 +308,8 @@ for the Serial Port Profile and other profiles used for telecommunication like Head-Set Profile, Hands-Free Profile, Object Exchange (OBEX) etc. -### RFCOMM flow control. -<a name="sec:flowcontrol"></a> + +### RFCOMM flow control {#sec:flowControlProtocols} RFCOMM has a mandatory credit-based flow-control. This means that two devices that established RFCOMM connection, use credits to keep track of @@ -326,24 +327,24 @@ is not much data transmitted and/or only one physical connection is used. If the management of credits is manual, credits are provided by the application such that it can manage its receive buffers explicitly. -### Access an RFCOMM service on a remote device -<a name="sec:rfcommlient"></a> + +### Access an RFCOMM service on a remote device {#sec:rfcommClientProtocols} To communicate with an RFCOMM service on a remote device, the application on a local Bluetooth device initiates the RFCOMM layer using the *rfcomm_init* function, and then creates an outgoing RFCOMM channel to a given server channel on a remote device using the *rfcomm_create_channel_internal* function. The -*rfcomm_create_channel_intern-al* function will initiate a new L2CAP +*rfcomm_create_channel_internal* function will initiate a new L2CAP connection for the RFCOMM multiplexer, if it does not already exist. The channel will automatically provide enough credits to the remote side. To provide credits manually, you have to create the RFCOMM connection by calling *rfcomm_create_channel_with_initial_credits_internal* - -see Section [on manual credit assignement](#sec:manualCredits). +see Section [on manual credit assignement](#sec:manualCreditsProtocols). The packet handler that is given as an input parameter of the RFCOMM create channel function will be assigned to the new outgoing channel. -This handler receives the RFCOMM_EVENT_OPEN_CHAN-NEL_COMPLETE and +This handler receives the RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE and RFCOMM_EVENT_CHANNEL_CLOSED events, and RFCOMM data packets, as shown in Listing [below](#lst:RFCOMMremoteService). @@ -376,8 +377,7 @@ Listing [below](#lst:RFCOMMremoteService). } -### Provide an RFCOMM service -<a name="sec:rfcomm_service"></a> +### Provide an RFCOMM service {#sec:rfcommServiceProtocols} To provide an RFCOMM service, the application on a local Bluetooth device must first init the L2CAP and RFCOMM layers and then register the @@ -449,8 +449,9 @@ provides the RFCOMM service example code. } } -### Living with a single output buffer -<a name="sec:single_buffer"></a> + +### Living with a single output buffer {#sec:singleBufferProtocols} + Outgoing packets, both commands and data, are not queued in BTstack. This section explains the consequences of this design decision for sending data and why it is not as bad as it sounds. @@ -533,7 +534,7 @@ Listing [below](#lst:SingleOutputBufferTryPH). If the management of credits is manual, credits are provided by the application such that it can manage its receive buffers explicitly, see -Listing [below]. +Listing [below](#lst:explicitFlowControl). <a name "lst:explicitFlowControl"></a> <!-- --> @@ -549,7 +550,7 @@ Listing [below]. Manual credit management is recommended when received RFCOMM data cannot -be processed immediately. In the [SPP flow control example](examples/#sec:sppflowcontrol), +be processed immediately. In the [SPP flow control example](examples/generated/#sec:sppflowcontrolExample), delayed processing of received data is simulated with the help of a periodic timer. To provide new credits, you call the *rfcomm_grant_credits* function with the RFCOMM channel ID @@ -572,8 +573,8 @@ for a minimal memory footprint. If possible, multiple RFCOMM buffers should be used to avoid pauses while the sender has to wait for a new credit. -### Slowing down RFCOMM data reception -<a name="sec:manualCredits"></a> + +### Slowing down RFCOMM data reception {#sec:manualCreditsProtocols} RFCOMM’s credit-based flow-control can be used to adapt, i.e., slow down the RFCOMM data to your processing speed. For incoming data, BTstack @@ -595,8 +596,7 @@ connection is used. See Listing [below](#lst:automaticFlowControl). } -SDP - Service Discovery Protocol --------------------------------- +## SDP - Service Discovery Protocol The SDP protocol allows to announce services and discover services provided by a remote Bluetooth device. @@ -627,11 +627,11 @@ a sub-DES. The returned pointer is used to add elements to this sub-DES. After adding all UUIDs, the sub-DES is “closed” with *de_pop_sequence*. -### Query remote SDP service -<a name="sec:querysdp"></a> + +### Query remote SDP service {#sec:querySDPProtocols} BTstack provides an SDP client to query SDP services of a remote device. -The SDP Client API is shown in [here](appendix/apis/#appendix:api_sdp). The +The SDP Client API is shown in [here](appendix/apis/#sec:sdpAPIAppendix). The *sdp_client_query* function initiates an L2CAP connection to the remote SDP server. Upon connect, a *Service Search Attribute* request with a *Service Search Pattern* and a *Attribute ID List* is sent. The @@ -735,11 +735,12 @@ of L2CAP, and it specifies a minimum L2CAP MTU of 1691 bytes. To receive BNEP events, please register a packet handler with *bnep_register_packet_handler*. -### Access a BNEP service on a remote device {#subsubsection:bnepclient} + +### Access a BNEP service on a remote device {#sec:bnepClientProtocols} To connect to a remote BNEP service, you need to know its UUID. The set of available UUIDs can be queried by a SDP query for the PAN profile. -Please see section on [PAN profile](profiles/#section:pan_profile) for details. +Please see section on [PAN profile](profiles/#sec:panProfiles) for details. With the remote UUID, you can create a connection using the *bnep_connect* function. You’ll receive a *BNEP_EVENT_OPEN_CHANNEL_COMPLETE* on success or failure. @@ -756,7 +757,8 @@ multicast filters with *bnep_set_net_type_filter* and Finally, to close a BNEP connection, you can call *bnep_disconnect*. -### Provide BNEP service {#subsubsection:bnepserver} + +### Provide BNEP service {#sec:bnepServiceProtocols} To provide a BNEP service, call *bnep_register_service* with the provided service UUID and a max frame size. @@ -781,11 +783,11 @@ attribute database and provided by the *att_server* implementation. The constant data are automatically served by the ATT server upon client request. To receive the dynamic data, such is characteristic value, the application needs to register read and/or write callback. In addition, -notifications and indications can be sent. Please see Section -[section:GATTClient] for more. +notifications and indications can be sent. Please see Section on +[GATT client](profiles/#sec:GATTClientProfiles) for more. -## SMP - Security Manager Protocol -<a name="section:smp"></a> + +## SMP - Security Manager Protocol {#sec:smpProtocols} The SMP protocol allows to setup authenticated and encrypted LE connection. After initialization and configuration, SMP handles security @@ -802,7 +804,8 @@ If you’re creating a product, you should also call *sm_set_ir()* and ER key seeds. If possible use a unique random number per device instead of deriving it from the product serial number or something similar. The encryption key generated by the BLE peripheral will be ultimately -derived from the ER key seed. See [Bluetooth Specification](https://www.bluetooth.org/Technical/Specifications/adopted.htm) - +derived from the ER key seed. See +[Bluetooth Specification](https://www.bluetooth.org/Technical/Specifications/adopted.htm) - Bluetooth Core V4.0, Vol 3, Part G, 5.2.2 for more details on deriving the different keys. The IR key is used to identify a device if private, resolvable Bluetooth addresses are used. diff --git a/docs/manual/markdown/docs/quick_start.md b/docs/manual/markdown/docs/quick_start.md index f6e24ccc3..a180a030d 100644 --- a/docs/manual/markdown/docs/quick_start.md +++ b/docs/manual/markdown/docs/quick_start.md @@ -16,7 +16,7 @@ and optionally git : Windows: Add Python installation folder to the Windows Path in Environment Variables. -Adding paths to the Windows Path variable <a name="sec:windowsPath"></a>: +### Adding paths to the Windows Path variable {#sec:windowsPathQuickStart} - Go to: Control Panel->System->Advanced tab->Environment Variables. @@ -33,7 +33,7 @@ Adding paths to the Windows Path variable <a name="sec:windowsPath"></a>: Use git to clone the latest version: - git clone https://github.com/bluekitchen/btstack.git + git clone https://github.com/bluekitchen/btstack.git Alternatively, you can download it as a ZIP archive from @@ -54,7 +54,8 @@ provided, too. ## Run the Example -As a first test, we recommend [the SPP Counter example](examples/generated/#section:sppcounter). During the startup, for TI chipsets, the init +As a first test, we recommend the [SPP Counter example](examples/generated/#sec:sppcounterExample). +During the startup, for TI chipsets, the init script is transferred, and the Bluetooth stack brought up. After that, the development board is discoverable as “BTstack SPP Counter” and provides a single virtual serial port. When you connect to it, you’ll @@ -83,8 +84,8 @@ Bluetooth. For this, execute: It’s also possible to run the examples on Win32 systems. For this: -- Install [MSYS](www.mingw.org/wiki/msys) and - [MINGW32](www.mingw.org) using the MINGW installer +- Install [MSYS](http://www.mingw.org/wiki/msys) and + [MINGW32](http://www.mingw.org) using the MINGW installer - Compile and install libusb-1.0.19 to [/usr/local/]() in msys command shell @@ -113,7 +114,7 @@ and installation instructions are provided on the On Windows, you need to download and extract [mspgcc](http://sourceforge.net/projects/mspgcc/files/Windows/mingw32/) to [C:\mspgcc](). Add [C:\mspgcc\bin]() folder to the Windows Path in Environment -variable as explained [here](#sec:windowsPath). +variable as explained [here](#sec:windowsPathQuickStart). **Loading Firmware.** To load firmware files onto the MSP430 MCU for the MSP-EXP430F5438 Experimeneter board, you need a programmer like the @@ -129,7 +130,7 @@ following software tools: <!-- --> - MSP430Flasher.exe -n MSP430F5438A -w "BINARY_FILE_NAME.hex" -v -g -z [VCC] + MSP430Flasher.exe -n MSP430F5438A -w "BINARY_FILE_NAME.hex" -v -g -z [VCC] - [MSPDebug](http://mspdebug.sourceforge.net/): @@ -175,9 +176,8 @@ the BLE part. The conversion script has been updated to detect *bluetooth_init_cc256x_1.2.bts* and adds *BLE_init_cc256x_1.2.bts* if present and merges them into a single .c file. -<a name="platform:msp430"></a> -### MSP-EXP430F5438 + CC256x Platform +### MSP-EXP430F5438 + CC256x Platform {#sec:platformMSP430QuickStart} **Hardware Setup.** We assume that a PAN1315, PAN1317, or PAN1323 module is plugged into RF1 and RF2 of the MSP-EXP430F5438 board and the “RF3 @@ -196,10 +196,11 @@ BTM805 Bluetooth module. In the port, the UART on the DAC daughter board was used for the debug output. Please remove the DAC board and connect a 3.3V USB-2-UART converter to GND and TX to get the debug output. -In [platforms/pic32-harmony](), a project file for the MPLAB X IDE is provided as well as a regular +In [platforms/pic32-harmony](), a project file for the MPLAB X IDE +is provided as well as a regular Makefile. Both assume that the MPLAB XC32 compiler is installed. The project is set to use -Os optimization which will cause warnings if you only have the Free version. It will still compile a working example. For this platform, we only provide the SPP and LE Counter example directly. -Other examples can be run by replacing the spp_and_le_counter.c file +Other examples can be run by replacing the *spp_and_le_counter.c* file with one of the other example files. diff --git a/docs/manual/markdown/markdown2mkdocs.py b/docs/manual/markdown/markdown2mkdocs.py new file mode 100755 index 000000000..c3f2a47e6 --- /dev/null +++ b/docs/manual/markdown/markdown2mkdocs.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python + +import sys, yaml +import os, re + +def insert_anchor(mdout, reference): + mdout.write("<a name=\"" + reference + "\"></a>\n\n") + +def insert_reference(mdout, text, link): + mdout.write("") + +def fcopy(source_file, dest_file): + with open(dest_file, 'w') as mdout: + with open(source_file, 'r') as mdin: + for line in mdin: + mdout.write(line) + +def process_sections(temp_file, dest_file): + with open(dest_file, 'w') as mdout: + with open(temp_file, 'r') as mdin: + for line in mdin: + section = re.match('(#+.*){#(sec:.*)}',line) + if section: + insert_anchor(mdout, section.group(2)) + mdout.write(section.group(1)+"\n") + else: + mdout.write(line) + + fcopy(dest_file, temp_file) + return + +def process_figures(temp_file, dest_file): + with open(dest_file, 'w') as mdout: + with open(temp_file, 'r') as mdin: + for line in mdin: + # detect figure + figure = re.match('\s*(\!.*)({#(fig:.*)})',line) + if figure: + insert_anchor(mdout, figure.group(3)) + mdout.write(figure.group(1)+"\n") + else: + figure_ref = re.match('.*({@(fig:.*)})',line) + if figure_ref: + md_reference = "[below](#"+figure_ref.group(2)+")" + line = line.replace(figure_ref.group(1), md_reference) + mdout.write(line) + fcopy(dest_file, temp_file) + return + +# def process_listings(temp_file, dest_file): +# with open(dest_file, 'w') as mdout: +# with open(temp_file, 'r') as mdin: +# for line in mdin: +# mdout.write(line) +# fcopy(dest_file, temp_file) +# return + +# def process_tables(temp_file, dest_file): +# with open(dest_file, 'w') as mdout: +# with open(temp_file, 'r') as mdin: +# for line in mdin: +# mdout.write(line) +# fcopy(dest_file, temp_file) +# return + + +def main(argv): + md_template = "docs" + md_temp = "docs_tmp" + md_final = "docs_final" + yml_file = "mkdocs.yml" + + with open(yml_file, 'r') as yin: + doc = yaml.load(yin) + for page in doc["pages"]: + source_file = md_template +"/"+ page[0] + temp_file = md_temp +"/"+ page[0] + dest_file = md_final +"/"+ page[0] + + process_sections(temp_file, dest_file) + process_figures(temp_file, dest_file) + # process_listings(temp_file, dest_file) + # process_tables(temp_file, dest_file) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/docs/manual/markdown/markdown2pdf.py b/docs/manual/markdown/markdown2pdf.py index a37cf2766..1eff3d821 100755 --- a/docs/manual/markdown/markdown2pdf.py +++ b/docs/manual/markdown/markdown2pdf.py @@ -24,9 +24,15 @@ def main(argv): with open(docs_folder +"/"+ md_file, 'r') as mdin: aout.write("\n\n#"+ title +"\n\n") for line in mdin: + # remove path from section reference + # e.g. [the SPP Counter example](examples/generated/#sec:sppcounterExample) + # replace with [the SPP Counter example](#sec:sppcounterExample) + section_ref = re.match('.*\(((.*)(#sec:.*))\).*',line) + if section_ref: + line = line.replace(section_ref.group(2),"") aout.write(line) - pandoc_cmd = "pandoc -f markdown -t latex --listings latex/btstack_generated.md -o latex/btstack_generated.tex" + pandoc_cmd = "pandoc -f markdown -t latex --filter pandoc-fignos --listings latex/btstack_generated.md -o latex/btstack_generated.tex" p = os.popen(pandoc_cmd,"r") while 1: line = p.readline() diff --git a/docs/manual/markdown/mkdocs.yml b/docs/manual/markdown/mkdocs.yml index c0f218869..90b737a99 100644 --- a/docs/manual/markdown/mkdocs.yml +++ b/docs/manual/markdown/mkdocs.yml @@ -1,5 +1,6 @@ site_name: BTstack Manual site_dir: btstack +docs_dir: docs_final pages: - [index.md, Welcome] - [quick_start.md, Quick Start] diff --git a/docs/manual/markdown/update_apis.py b/docs/manual/markdown/update_apis.py index 22ec002d7..8f400c2ee 100755 --- a/docs/manual/markdown/update_apis.py +++ b/docs/manual/markdown/update_apis.py @@ -16,8 +16,7 @@ code_identation = " " api_header = """ -## API_TITLE API -<a name ="appendix:API_LABLE"></a> +## API_TITLE API {#sec:API_LABLEAPIAppendix} """ @@ -26,18 +25,18 @@ api_ending = """ # [file_name, api_title, api_lable] list_of_apis = [ - [btstack_folder+"include/btstack/run_loop.h", "Run Loop", "api_run_loop"], - [btstack_folder+"src/hci.h", "HCI", "api_hci"], - [btstack_folder+"src/l2cap.h", "L2CAP", "api_l2cap"], - [btstack_folder+"src/rfcomm.h", "RFCOMM", "api_rfcomm"], - [btstack_folder+"src/sdp.h", "SDP", "api_sdp"], - [btstack_folder+"src/sdp_client.h", "SDP Client", "api_sdp_client"], - [btstack_folder+"src/sdp_query_rfcomm.h", "SDP RFCOMM Query", "api_sdp_queries"], - [btstack_folder+"ble/gatt_client.h", "GATT Client", "api_gatt_client"], - [btstack_folder+"src/pan.h", "PAN", "api_pan"], - [btstack_folder+"src/bnep.h", "BNEP", "api_bnep"], - [btstack_folder+"src/gap.h", "GAP", "api_gap"], - [btstack_folder+"ble/sm.h", "SM", "api_sm"] + [btstack_folder+"include/btstack/run_loop.h", "Run Loop", "runLoop"], + [btstack_folder+"src/hci.h", "HCI", "hci"], + [btstack_folder+"src/l2cap.h", "L2CAP", "l2cap"], + [btstack_folder+"src/rfcomm.h", "RFCOMM", "rfcomm"], + [btstack_folder+"src/sdp.h", "SDP", "sdp"], + [btstack_folder+"src/sdp_client.h", "SDP Client", "sdpClient"], + [btstack_folder+"src/sdp_query_rfcomm.h", "SDP RFCOMM Query", "sdpQueries"], + [btstack_folder+"ble/gatt_client.h", "GATT Client", "gattClient"], + [btstack_folder+"src/pan.h", "PAN", "pan"], + [btstack_folder+"src/bnep.h", "BNEP", "bnep"], + [btstack_folder+"src/gap.h", "GAP", "gap"], + [btstack_folder+"ble/sm.h", "SM", "sm"] ] def replacePlaceholder(template, title, lable): diff --git a/docs/manual/markdown/update_listings.py b/docs/manual/markdown/update_listings.py index bd088b9b6..ee02d9b48 100755 --- a/docs/manual/markdown/update_listings.py +++ b/docs/manual/markdown/update_listings.py @@ -32,12 +32,11 @@ examples_header = """ """ example_item = """ - - [EXAMPLE_TITLE](#section:EXAMPLE_LABEL): EXAMPLE_DESC. + - [EXAMPLE_TITLE](#sec:EXAMPLE_LABELExample): EXAMPLE_DESC. """ example_section = """ -## EXAMPLE_TITLE: EXAMPLE_DESC -<a name="section:EXAMPLE_LABEL"></a> +## EXAMPLE_TITLE: EXAMPLE_DESC {#sec:EXAMPLE_LABELExample} """ example_subsection = """ @@ -72,7 +71,7 @@ def latexText(text, ref_prefix): refs = re.match('.*(Section\s+)(\w+).*',brief) if refs: brief = brief.replace(refs.group(1), "[here]") - brief = brief.replace(refs.group(2), "(#section:"+refs.group(2)+")") + brief = brief.replace(refs.group(2), "(#sec:"+refs.group(2)+")") return brief