manual: corrected listing refs for latex

This commit is contained in:
Milanka Ringwald 2015-06-24 16:47:05 +02:00
parent 06258e9070
commit 4c719da614
12 changed files with 86 additions and 97 deletions

View File

@ -75,9 +75,9 @@ by RFCOMM:
Possible errors: an L2CAP error, out of memory.
- RFCOMM_EVENT_CREDITS - The application can resume sending when
this even is received. See Section [section:flowcontrol] for more on
RFCOMM credit-based flow-control.
this even is received. See Section on [RFCOMM credit-based flow-control]{protocols/#sec:flowControlProtocols}
for more.
- RFCOMM_EVENT_SERVICE_REGISTERED - Status not equal zero indicates
an error. Possible errors:
@ -109,7 +109,7 @@ RFCOMM event paramaters, with size in bits:
- RFCOMM_EVENT_SERVICE_REGISTERED:
- *event(8), len(8), status(8), rfcomm server channel_id(8)*
## Errors
## Errors {#sec:errorsAppendix}
Error | Error Code

View File

@ -26,8 +26,6 @@ events and data coming from either the Main Application or from BTstack
via registered packet handlers (PH). BTstacks Run Loop is responsible
for providing timers and processing incoming data.
<a name="fig:BTstackArchitecture"></a>
![Architecture of a BTstack-based application.](picts/btstack-architecture.png) {#fig:BTstackArchitecture}
## Single threaded design

View File

@ -10,7 +10,7 @@ common init code.
Listing [below](#lst:btstackInit) shows a minimal platform setup for an
embedded system with a Bluetooth chipset connected via UART.
<a name="lst:btstackInit"></a>
~~~~ {#lst:btstackInit .c caption="{Minimal platform setup for an embedded system}"}
int main(){
// ... hardware init: watchdoch, IOs, timers, etc...
@ -35,6 +35,8 @@ embedded system with a Bluetooth chipset connected via UART.
// go
run_loop_execute();
}
~~~~
First, BTstacks memory pools are setup up. Then, the standard run loop
implementation for embedded systems is selected.

View File

@ -21,12 +21,12 @@ allocated in two different manners:
elements is defined in the config file. To initialize the static
pools, you need to call *btstack_memory_init* function. An example
of memory configuration for a single SPP service with a minimal
L2CAP MTU is shown in Listing [below](#lst:memoryConfigurationSPP).
L2CAP MTU is shown in Listing {@lst:memoryConfigurationSPP}.
- dynamically using the *malloc/free* functions, if HAVE_MALLOC is
defined in config file.
<a name "lst:memoryConfigurationSPP"></a>
<!-- a name "lst:memoryConfigurationSPP"></a-->
<!-- -->
#define HCI_ACL_PAYLOAD_SIZE 52
@ -41,6 +41,8 @@ allocated in two different manners:
#define MAX_NO_DB_MEM_LINK_KEYS 3
#define MAX_NO_DB_MEM_SERVICES 1
Listing: Title. {#lst:memoryConfigurationSPP}
If both HAVE_MALLOC and maximal size of a pool are defined in the
config file, the statical allocation will take precedence. In case that
both are omitted, an error will be raised.

View File

@ -147,8 +147,8 @@ system. As an example and for testing purposes, BTstack provides the
memory-only implementation *remote_device_db_memory*. An
implementation has to conform to the interface in Listing [below](#lst:persistentDB).
<a name="lst:persistentDB"></a>
~~~~ {#lst:persistentDB .c caption="{Persistent storage interface.}"}
typedef struct {
// management
void (*open)();
@ -164,3 +164,4 @@ implementation has to conform to the interface in Listing [below](#lst:persisten
void(*put_name)(bd_addr_t bd_addr, device_name_t *device_name);
void(*delete_name)(bd_addr_t bd_addr);
} remote_device_db_t;
~~~~

View File

@ -21,7 +21,7 @@ $gap_set_local_name$. To save energy, you may set the device as
undiscoverable again, once a connection is established. See Listing
[below](#lst:Discoverable) for an example.
<a name="lst:Discoverable"></a>
~~~~ {#lst:Discoverable .c caption="{Setting discoverable mode.}"}
int main(void){
...
@ -39,8 +39,9 @@ undiscoverable again, once a connection is established. See Listing
...
}
}
~~~~
### Discover remote devices {#section:DiscoverRemoteDevices}
### Discover remote devices {#sec:GAPdiscoverRemoteDevices}
To scan for remote devices, the *hci_inquiry* command is used. Found
remote devices are reported as a part of:
@ -57,7 +58,7 @@ add information about the received signal strength or provide the
Extended Inquiry Result (EIR). A code snippet is shown in Listing
[below](#lst:DiscoverDevices).
<a name="lst:DiscoverDevices"></a>
~~~~ {#lst:DiscoverDevices .c caption="{Discover remote devices.}"}
void print_inquiry_results(uint8_t *packet){
int event = packet[0];
@ -103,6 +104,7 @@ Extended Inquiry Result (EIR). A code snippet is shown in Listing
...
}
}
~~~~
By default, neither RSSI values nor EIR are reported. If the Bluetooth
device implements Bluetooth Specification 2.1 or higher, the
@ -126,7 +128,7 @@ both sides. This isnt optimal for embedded systems that do not have
full I/O capabilities. To support pairing with older devices using a
PIN, see Listing [below](#lst:PinCodeRequest).
<a name="lst:PinCodeRequest"></a>
~~~~ {#lst:PinCodeRequest .c caption="{PIN code request.}"}
void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
...
@ -142,6 +144,7 @@ PIN, see Listing [below](#lst:PinCodeRequest).
...
}
}
~~~~
The Bluetooth v2.1 specification introduces Secure Simple Pairing (SSP),
which is a better approach as it both improves security and is better
@ -178,10 +181,10 @@ two Bluetooth enabled devices.
### Accessing an SPP Server on a remote device
To access a remote SPP server, you first need to query the remote device
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
for its SPP services. Section [on querying remote SDP service](#sec:querySDPProtocols)
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:rfcommClientProtocols).
### Providing an SPP Server
@ -231,8 +234,8 @@ Currently, BTstack supports only PANU.
To access a remote PANU service, you first need perform an SDP query to
get the L2CAP PSM for the requested PANU UUID. With these two pieces of
information, you can connect BNEP to the remote PANU service with the
*bnep_connect* function. The PANU Demo example in Section
[example:panudemo] shows how this is accomplished.
*bnep_connect* function. The Section on [PANU Demo example](#exaples/#sec:panudemoExample)
shows how this is accomplished.
### Providing a PANU service
@ -371,7 +374,9 @@ GATT profiles are defined by a simple textual comma separated value
(.csv) representation. While the description is easy to read and edit,
it is compact and can be placed in ROM.
The current format is:
The current format is shown in Listing [below](#lst:GATTServerProfile).
~~~~ {#lst:GATTServerProfile .c caption="{GATT profile.}"}
PRIMARY_SERVICE, {SERVICE_UUID}
CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE}
@ -380,6 +385,7 @@ The current format is:
PRIMARY_SERVICE, {SERVICE_UUID}
CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE}
...
~~~~
Properties can be a list of READ $|$ WRITE $|$ WRITE_WITHOUT_RESPONSE
$|$ NOTIFY $|$ INDICATE $|$ DYNAMIC.

View File

@ -71,8 +71,7 @@ Core Version 4.0, Volume 2, Part E, Chapter 5.4.
Listing [below](#lst:hciOGFs) shows the OGFs provided by BTstack in file [src/hci.h]():
<a name "lst:hciOGFs"></a>
<!-- -->
~~~~ {#lst:hciOGFs .c caption="{HCI OGFs provided by BTstack.}"}
#define OGF_LINK_CONTROL 0x01
#define OGF_LINK_POLICY 0x02
@ -81,6 +80,7 @@ Listing [below](#lst:hciOGFs) shows the OGFs provided by BTstack in file [src/hc
#define OGF_LE_CONTROLLER 0x08
#define OGF_BTSTACK 0x3d
#define OGF_VENDOR 0x3f
~~~~
For all existing Bluetooth
commands and their OCFs see [Bluetooth Specification](https://www.bluetooth.org/Technical/Specifications/adopted.htm) -
@ -93,8 +93,7 @@ struct as a compact format to define HCI command packets, see
Listing [below](#lst:HCIcmdTemplate), and [include/btstack/hci_cmds.h]()
file in the source code.
<a name "lst:HCIcmdTemplate"></a>
<!-- -->
~~~~ {#lst:HCIcmdTemplate .c caption="{HCI command struct.}"}
// Calculate combined ogf/ocf value.
#define OPCODE(ogf, ocf) (ocf | ogf << 10)
@ -104,19 +103,19 @@ file in the source code.
uint16_t opcode;
const char *format;
} hci_cmd_t;
~~~~
Listing [below](#lst:HCIcmdExample) illustrates the *hci_write_local_name* HCI
command template from library:
<a name "lst:HCIcmdExample"></a>
<!-- -->
~~~~ {#lst:HCIcmdExample .c caption="{HCI command example.}"}
// Sets local Bluetooth name
const hci_cmd_t hci_write_local_name = {
OPCODE(OGF_CONTROLLER_BASEBAND, 0x13), "N"
// Local name (UTF-8, Null Terminated, max 248 octets)
};
~~~~
It uses OGF_CONTROLLER_BASEBAND as OGF,
0x13 as OCF, and has one parameter with format “N” indicating a null
@ -153,13 +152,12 @@ if it is ok to send.
Listing [below](#lst:HCIcmdExampleLocalName) illustrates how to manually set the
device name with the HCI Write Local Name command.
<a name "lst:HCIcmdExampleLocalName"></a>
<!-- -->
~~~~ {#lst:HCIcmdExampleLocalName .c caption="{Sending HCI command example.}"}
if (hci_can_send_packet_now(HCI_COMMAND_DATA_PACKET)){
hci_send_cmd(&hci_write_local_name, "BTstack Demo");
}
~~~~
Please note, that an application rarely has to send HCI commands on its
own. Instead, BTstack provides convenience functions in GAP and higher
@ -196,8 +194,8 @@ handler receives the L2CAP_EVENT_CHANNEL_OPENED and
L2CAP_EVENT_CHANNEL_CLOSED events and L2CAP data packets, as shown
in Listing [below](#lst:L2CAPremoteService).
<a name "lst:L2CAPremoteService"></a>
<!-- -->
~~~~ {#lst:L2CAPremoteService .c caption="{Accessing an L2CAP service on a remote device.}"}
btstack_packet_handler_t l2cap_packet_handler;
@ -224,7 +222,7 @@ in Listing [below](#lst:L2CAPremoteService).
return;
}
}
~~~~
### Provide an L2CAP service
@ -248,8 +246,8 @@ BTstack outgoing buffer became free again, the second one signals the
same for ACL buffers in the Bluetooth chipset. Listing [below](#lst:L2CAPService)
provides L2CAP service example code.
<a name "lst:L2CAPService"></a>
<!-- -->
~~~~ {#lst:L2CAPService .c caption="{Providing an L2CAP service.}"}
void btstack_setup(){
...
@ -292,7 +290,7 @@ provides L2CAP service example code.
break;
}
}
~~~~
### L2CAP LE - L2CAP Low Energy Protocol
@ -350,9 +348,9 @@ 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).
<a name "lst:RFCOMMremoteService"></a>
<!-- -->
~~~~ {#lst:RFCOMMremoteService .c caption="{RFCOMM handler for outgoing RFCOMM channel.}"}
void init_rfcomm(){
...
rfcomm_init();
@ -377,7 +375,7 @@ Listing [below](#lst:RFCOMMremoteService).
return;
}
}
~~~~
### Provide an RFCOMM service {#sec:rfcommServiceProtocols}
@ -404,8 +402,8 @@ BTstack outgoing buffer became free again, the second one signals that
the remote side allowed to send another packet. Listing [below](#lst:RFCOMMService)
provides the RFCOMM service example code.
<a name "lst:RFCOMMService"></a>
<!-- -->
~~~~ {#lst:RFCOMMService .c caption="{Providing an RFCOMM service.}"}
void btstack_setup(){
...
@ -450,7 +448,7 @@ provides the RFCOMM service example code.
break;
}
}
~~~~
### Living with a single output buffer {#sec:singleBufferProtocols}
@ -470,9 +468,7 @@ full and RFCOMM_NO_OUTGOING_CREDITS, if no outgoing credits are
available. In Listing [below](#lst:SingleOutputBufferTryToSend), we show how to
resend data packets when credits or outgoing buffers become available.
<a name "lst:SingleOutputBufferTryToSend"></a>
<!-- -->
~~~~ {#lst:SingleOutputBufferTryToSend .c caption="{Preparing and sending data.}"}
void prepareData(void){
...
}
@ -495,7 +491,7 @@ resend data packets when credits or outgoing buffers become available.
break;
}
}
~~~~
RFCOMMs mandatory credit-based flow-control imposes an additional
constraint on sending a data packet - at least one new RFCOMM credit
@ -504,12 +500,11 @@ sending an RFCOMM credit (RFCOMM_EVENT_CREDITS) event.
These two events represent two orthogonal mechanisms that deal with flow
control. Taking these mechanisms in account, the application should try
to send data packets when one of these two events is received. For a RFCOMM example see
Listing [below](#lst:SingleOutputBufferTryPH).
to send data packets when one of these two events is received. For an
RFCOMM example see Listing [below](#lst:SingleOutputBufferTryPH).
<a name "lst:SingleOutputBufferTryPH"></a>
<!-- -->
~~~~ {#lst:SingleOutputBufferTryPH .c caption="{Resending data packets.}"}
void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
...
@ -533,14 +528,14 @@ 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](#lst:explicitFlowControl).
<a name "lst:explicitFlowControl"></a>
<!-- -->
~~~~ {#lst:explicitFlowControl .c caption="{RFCOMM service with manual credit management.}"}
void btstack_setup(void){
...
// init RFCOMM
@ -549,7 +544,7 @@ Listing [below](#lst:explicitFlowControl).
// reserved channel, mtu=100, 1 credit
rfcomm_register_service_with_initial_credits_internal(NULL, rfcomm_channel_nr, 100, 1);
}
~~~~
Manual credit management is recommended when received RFCOMM data cannot
be processed immediately. In the [SPP flow control example](examples/generated/#sec:sppflowcontrolExample),
@ -558,15 +553,14 @@ simulated with the help of a periodic timer. To provide new credits, you
call the *rfcomm_grant_credits* function with the RFCOMM channel ID
and the number of credits as shown in Listing [below](#lst:NewCredits).
<a name "lst:NewCredits"></a>
<!-- -->
~~~~ {#lst:NewCredits .c caption="{Granting RFCOMM credits.}"}
void processing(){
// process incoming data packet
...
// provide new credit
rfcomm_grant_credits(rfcomm_channel_id, 1);
}
~~~~
Please note that providing single credits effectively reduces the credit-based
(sliding window) flow control to a stop-and-wait flow-control that
@ -585,10 +579,8 @@ management. If the management of credits is automatic, new credits
are provided when needed relying on ACL flow control. This is only
useful if there is not much data transmitted and/or only one physical
connection is used. See Listing [below](#lst:automaticFlowControl).
<a name "lst:automaticFlowControl"></a>
<!-- -->
~~~~ {#lst:automaticFlowControl .c caption="{RFCOMM service with automatic credit management.}"}
void btstack_setup(void){
...
// init RFCOMM
@ -596,7 +588,7 @@ connection is used. See Listing [below](#lst:automaticFlowControl).
rfcomm_register_packet_handler(packet_handler);
rfcomm_register_service_internal(NULL, rfcomm_channel_nr, 100);
}
~~~~
## SDP - Service Discovery Protocol
@ -651,8 +643,8 @@ service. The query delivers all matching RFCOMM services, including its
name and the channel number, as well as a query complete event via a
registered callback, as shown in Listing [below](#lst:SDPClientRFCOMM).
<a name "lst:SDPClientRFCOMM"></a>
<!-- -->
~~~~ {#lst:SDPClientRFCOMM .c caption="{Searching RFCOMM services on a remote device.}"}
bd_addr_t remote = {0x04,0x0C,0xCE,0xE4,0x85,0xD3};
@ -708,23 +700,7 @@ registered callback, as shown in Listing [below](#lst:SDPClientRFCOMM).
run_loop_execute();
return 0;
}
uint8_t des_buffer[200];
uint8_t* attribute;
de_create_sequence(service);
// 0x0000 "Service Record Handle"
de_add_number(des_buffer, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle);
de_add_number(des_buffer, DE_UINT, DE_SIZE_32, 0x10001);
// 0x0001 "Service Class ID List"
de_add_number(des_buffer, DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList);
attribute = de_push_sequence(des_buffer);
{
de_add_number(attribute, DE_UUID, DE_SIZE_16, 0x1101 );
}
de_pop_sequence(des_buffer, attribute);
~~~~
## BNEP - Bluetooth Network Encapsulation Protocol

View File

@ -25,6 +25,12 @@ def fix_listing_after_section(line):
line = "\leavevmode" + line
return line
def fix_listing_hyperref_into_ref(line):
corr = re.match('(.*\\\\)hyperref\[(lst:.*)\]{.*}(.*)',line)
if corr:
line = corr.group(1)+"ref{" + corr.group(2) +"} " + corr.group(3)
return line
def fix_figure_width_and_type(line):
global figures
@ -83,6 +89,7 @@ def main(argv):
for line in fin:
line = fix_empty_href(line)
line = fix_listing_after_section(line)
line = fix_listing_hyperref_into_ref(line)
line = fix_figure_width_and_type(line)
line = fix_appendix_pagebreak(line)
aout.write(line)

View File

@ -43,14 +43,17 @@ example_subsection = """
### SECTION_TITLE
"""
listing_reference = """[here](#lst:FILE_NAMELISTING_LABEL)
"""
listing_start = """
<a name="FILE_NAME:LISTING_LABEL"></a>
<!-- -->
~~~~ {#lst:FILE_NAMELISTING_LABEL .c caption="{LISTING_CAPTION}"}
"""
listing_ending = """
~~~~
"""
@ -65,13 +68,7 @@ def latexText(text, ref_prefix):
refs = re.match('.*(Listing\s+)(\w+).*',brief)
if refs:
brief = brief.replace(refs.group(1), "[code snippet below]")
brief = brief.replace(refs.group(2), "(#"+ref_prefix+":" + refs.group(2)+")")
refs = re.match('.*(Section\s+)(\w+).*',brief)
if refs:
brief = brief.replace(refs.group(1), "[here]")
brief = brief.replace(refs.group(2), "(#sec:"+refs.group(2)+")")
brief = brief.replace(refs.group(2), "[here](#lst:"+ref_prefix + refs.group(2)+")")
return brief

View File

@ -236,7 +236,7 @@ static void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size)
}
/* @text For more details on discovering remote devices, please see
* Section DiscoverRemoteDevices.
* Section on [GAP](profiles/#sec:GAPdiscoverRemoteDevices).
*/

View File

@ -98,7 +98,7 @@ static int service_index = 0;
* packet handlers, as shown in Listing GATTClientSetup.
* Additionally, the security manager can be setup, if signed writes, or
* encrypted, or authenticated connection are required, to access the
* characteristics, as explained in Section smp.
* characteristics, as explained in Section on [SMP](protocols/#sec:smpProtocols).
*/
/* LISTING_START(GATTClientSetup): Setting up GATT client */

View File

@ -314,8 +314,8 @@ char * get_string_from_data_element(uint8_t * element){
/* @section SDP parser callback
*
* @text The SDP parsers retrieves the BNEP PAN UUID as explained in Section
* \ref{example:sdpbnepquery}.
* @text The SDP parsers retrieves the BNEP PAN UUID as explained in
* Section [on SDP BNEP Query example](examples/#sec:sdpbnepqueryExample}.
*/
static void handle_sdp_client_query_result(sdp_query_event_t *event)
{