mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-25 09:35:42 +00:00
manual: script ignores text flag in listing, it writes it afterwards
This commit is contained in:
parent
be0cb7577b
commit
f190958be3
@ -45,7 +45,7 @@ example_subsection = """
|
||||
"""
|
||||
|
||||
listing_start = """
|
||||
\\begin{lstlisting}[float, caption= LISTING_CAPTION., label=listing:LISTING_LABLE]
|
||||
\\begin{lstlisting}[caption= LISTING_CAPTION., label=listing:LISTING_LABLE]
|
||||
"""
|
||||
|
||||
listing_ending = """\end{lstlisting}
|
||||
@ -55,9 +55,9 @@ msp_folder = "../../platforms/msp-exp430f5438-cc2564b/example/"
|
||||
embedded_folder = "../../example/embedded/"
|
||||
# Example group title: [folder, example file, section title]
|
||||
list_of_examples = {
|
||||
"UART" : [[msp_folder, "led_counter", "UART and timer interrupt without Bluetooth"]],
|
||||
"GAP" : [[embedded_folder, "gap_inquiry", "GAP Inquiry Example"]],
|
||||
#"SPP Server" : [[embedded_folder, "spp_counter", "SPP Server - Heartbeat Counter over RFCOMM"],
|
||||
#"UART" : [[msp_folder, "led_counter", "UART and timer interrupt without Bluetooth"]],
|
||||
#"GAP" : [[embedded_folder, "gap_inquiry", "GAP Inquiry Example"]],
|
||||
"SPP Server" : [[embedded_folder, "spp_counter", "SPP Server - Heartbeat Counter over RFCOMM"]]
|
||||
# [embedded_folder, "spp_accel", "SPP Server - Accelerator Values"],
|
||||
# [embedded_folder, "spp_flowcontrol", "SPP Server - Flow Control"]],
|
||||
#"HID Host" :[[embedded_folder, "hid_demo", "HID Demo"]],
|
||||
@ -96,6 +96,7 @@ def latexText(text):
|
||||
def writeListings(fout, infile_name):
|
||||
itemText = None
|
||||
state = State.SearchExampleStart
|
||||
briefs_in_listings = ""
|
||||
|
||||
with open(infile_name, 'rb') as fin:
|
||||
for line in fin:
|
||||
@ -125,7 +126,8 @@ def writeListings(fout, infile_name):
|
||||
brief = None
|
||||
brief_start = re.match('.*(@text)\s*(.*)',line)
|
||||
if brief_start:
|
||||
aout.write("\n\n" + latexText(brief_start.group(2)))
|
||||
brief_part = "\n\n" + latexText(brief_start.group(2))
|
||||
briefs_in_listings = briefs_in_listings + brief_part
|
||||
continue
|
||||
|
||||
# detect subsequent items
|
||||
@ -156,7 +158,8 @@ def writeListings(fout, infile_name):
|
||||
|
||||
brief_continue = re.match('(\s*\*\s)(.*)\s*\n',line)
|
||||
if brief_continue:
|
||||
aout.write(" " + latexText(brief_continue.group(2)))
|
||||
brief_part = " " + latexText(brief_continue.group(2))
|
||||
briefs_in_listings = briefs_in_listings + brief_part
|
||||
continue
|
||||
|
||||
if state == State.SearchListingStart:
|
||||
@ -172,19 +175,22 @@ def writeListings(fout, infile_name):
|
||||
continue
|
||||
|
||||
if state == State.SearchListingEnd:
|
||||
print "END"
|
||||
parts_end = re.match('.*(LISTING_END).*',line)
|
||||
parts_pause = re.match('.*(LISTING_PAUSE).*',line)
|
||||
end_comment_parts = re.match('.*(\*/)\s*\n', line);
|
||||
|
||||
if not parts_end and not parts_pause:
|
||||
end_comment_parts = re.match('.*(\*)/*\s*\n', line);
|
||||
if not end_comment_parts:
|
||||
aout.write(line)
|
||||
elif parts_end:
|
||||
if parts_end:
|
||||
aout.write(listing_ending)
|
||||
if briefs_in_listings:
|
||||
aout.write(briefs_in_listings)
|
||||
briefs_in_listings = ""
|
||||
state = State.SearchListingStart
|
||||
elif parts_pause:
|
||||
aout.write("...\n")
|
||||
state = State.SearchListingResume
|
||||
elif not end_comment_parts:
|
||||
aout.write(line)
|
||||
continue
|
||||
|
||||
if state == State.SearchListingResume:
|
||||
@ -198,6 +204,9 @@ def writeListings(fout, infile_name):
|
||||
if state != State.SearchListingStart:
|
||||
print "Formating error detected"
|
||||
state = State.ReachedExampleEnd
|
||||
if briefs_in_listings:
|
||||
aout.write(briefs_in_listings)
|
||||
briefs_in_listings = ""
|
||||
print "Reached end of the example"
|
||||
|
||||
|
||||
|
@ -133,7 +133,6 @@ static void continue_remote_names(){
|
||||
* @text The Bluetooth logic is implemented as a state machine within the packet
|
||||
* handler. In this example, the following states are passed sequentially:
|
||||
* INIT, and ACTIVE.
|
||||
|
||||
*/
|
||||
|
||||
static void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
|
||||
|
@ -36,9 +36,12 @@
|
||||
*/
|
||||
|
||||
// *****************************************************************************
|
||||
//
|
||||
// minimal setup for HCI code
|
||||
//
|
||||
/* EXAMPLE_START(spp_counter): SPP Server - Heartbeat Counter over RFCOMM
|
||||
*
|
||||
* @text The Serial port profile (SPP) is widely used as it provides a serial
|
||||
* port over Bluetooth. The SPP counter example demonstrates how to setup an SPP
|
||||
* service, and provide a periodic timer over RFCOMM.
|
||||
*/
|
||||
// *****************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
@ -69,113 +72,25 @@ static uint16_t rfcomm_channel_id;
|
||||
static uint8_t spp_service_buffer[150];
|
||||
static timer_source_t heartbeat;
|
||||
|
||||
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
bd_addr_t event_addr;
|
||||
uint8_t rfcomm_channel_nr;
|
||||
uint16_t mtu;
|
||||
int i;
|
||||
|
||||
switch (packet_type) {
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (packet[0]) {
|
||||
|
||||
case BTSTACK_EVENT_STATE:
|
||||
// bt stack activated, get started - set local name
|
||||
if (packet[2] == HCI_STATE_WORKING) {
|
||||
printf("BTstack is up and running\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVENT_COMMAND_COMPLETE:
|
||||
if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){
|
||||
bt_flip_addr(event_addr, &packet[6]);
|
||||
printf("BD-ADDR: %s\n", bd_addr_to_str(event_addr));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PIN_CODE_REQUEST:
|
||||
// inform about pin code request
|
||||
printf("Pin code request - using '0000'\n");
|
||||
bt_flip_addr(event_addr, &packet[2]);
|
||||
hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
|
||||
break;
|
||||
|
||||
case HCI_EVENT_USER_CONFIRMATION_REQUEST:
|
||||
// inform about user confirmation request
|
||||
printf("SSP User Confirmation Request with numeric value '%06u'\n", READ_BT_32(packet, 8));
|
||||
printf("SSP User Confirmation Auto accept\n");
|
||||
break;
|
||||
|
||||
|
||||
case RFCOMM_EVENT_INCOMING_CONNECTION:
|
||||
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
|
||||
bt_flip_addr(event_addr, &packet[2]);
|
||||
rfcomm_channel_nr = packet[8];
|
||||
rfcomm_channel_id = READ_BT_16(packet, 9);
|
||||
printf("RFCOMM channel %u requested for %s\n", rfcomm_channel_nr, bd_addr_to_str(event_addr));
|
||||
rfcomm_accept_connection_internal(rfcomm_channel_id);
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
|
||||
// data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
|
||||
if (packet[2]) {
|
||||
printf("RFCOMM channel open failed, status %u\n", packet[2]);
|
||||
} else {
|
||||
rfcomm_channel_id = READ_BT_16(packet, 12);
|
||||
mtu = READ_BT_16(packet, 14);
|
||||
printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu);
|
||||
}
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_CHANNEL_CLOSED:
|
||||
printf("RFCOMM channel closed\n");
|
||||
rfcomm_channel_id = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RFCOMM_DATA_PACKET:
|
||||
printf("RCV: '");
|
||||
for (i=0;i<size;i++){
|
||||
putchar(packet[i]);
|
||||
}
|
||||
printf("'\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void heartbeat_handler(struct timer *ts){
|
||||
|
||||
static int counter = 0;
|
||||
|
||||
if (rfcomm_channel_id){
|
||||
char lineBuffer[30];
|
||||
sprintf(lineBuffer, "BTstack counter %04u\n", ++counter);
|
||||
printf("%s", lineBuffer);
|
||||
if (rfcomm_can_send_packet_now(rfcomm_channel_id)) {
|
||||
int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer));
|
||||
if (err) {
|
||||
log_error("rfcomm_send_internal -> error 0X%02x", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS);
|
||||
run_loop_add_timer(ts);
|
||||
}
|
||||
|
||||
int btstack_main(int argc, const char * argv[]);
|
||||
int btstack_main(int argc, const char * argv[]){
|
||||
|
||||
hci_discoverable_control(1);
|
||||
/* @section SPP Service Setup
|
||||
*
|
||||
* @text SPP is based on RFCOMM, a Bluetooth protocol that emulates RS-232 serial
|
||||
* ports. To access an RFCOMM serial port on a remote device, a client has to
|
||||
* query its Service Discovery Protocol (SDP) server. The SDP response for an SPP
|
||||
* service contains the RFCOMM channel number. To provide an SPP service, you need
|
||||
* to initialize memory and the run loop, setup HCI and L2CAP, then register an
|
||||
* RFCOMM service and provide its RFCOMM channel number as part of the Protocol
|
||||
* List attribute of the SDP record. Example code for SPP service setup is
|
||||
* provided in Listing SPPSetup. The SDP record created by
|
||||
* $sdp_create_spp_service$ consists of a basic SPP definition that uses provided
|
||||
* RFCOMM channel ID and service name. For more details, please have a look at it
|
||||
* in \path{include/btstack/sdp_util.c}. The SDP record is created on the fly in
|
||||
* RAM and is deterministic. To preserve valuable RAM, the result can be stored as
|
||||
* constant data inside the ROM.
|
||||
*/
|
||||
|
||||
/* LISTING_START(SPPSetup): SPP service setup */
|
||||
int spp_service_setup(){
|
||||
l2cap_init();
|
||||
l2cap_register_packet_handler(packet_handler);
|
||||
|
||||
@ -196,18 +111,163 @@ int btstack_main(int argc, const char * argv[]){
|
||||
printf("SDP service record size: %u\n", de_get_len(spp_service_buffer));
|
||||
sdp_register_service_internal(NULL, spp_service_buffer);
|
||||
#endif
|
||||
}
|
||||
/* LISTING_END */
|
||||
|
||||
hci_ssp_set_io_capability(SSP_IO_CAPABILITY_DISPLAY_YES_NO);
|
||||
/* @section Periodic Timer Setup
|
||||
*
|
||||
* @text The heartbeat handler increases the real counter every second,
|
||||
* as shown in Listing PeriodicCounter.
|
||||
*/
|
||||
|
||||
/* LISTING_START(PeriodicCounter): Periodic Counter */
|
||||
static void heartbeat_handler(struct timer *ts){
|
||||
static int counter = 0;
|
||||
|
||||
if (rfcomm_channel_id){
|
||||
char lineBuffer[30];
|
||||
sprintf(lineBuffer, "BTstack counter %04u\n", ++counter);
|
||||
printf("%s", lineBuffer);
|
||||
if (rfcomm_can_send_packet_now(rfcomm_channel_id)) {
|
||||
int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer));
|
||||
if (err) {
|
||||
log_error("rfcomm_send_internal -> error 0X%02x", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS);
|
||||
run_loop_add_timer(ts);
|
||||
}
|
||||
/* LISTING_END */
|
||||
|
||||
|
||||
/* @section Bluetooth Logic
|
||||
* @text The Bluetooth logic is implemented within the
|
||||
* packet handler, see Listing SppServerPacketHandler. In this example,
|
||||
* the following events are passed sequentially:
|
||||
* - BTSTACK_EVENT_STATE,
|
||||
* - HCI_EVENT_PIN_CODE_REQUEST or HCI_EVENT_USER_CONFIRMATION_REQUEST,
|
||||
* - RFCOMM_EVENT_INCOMING_CONNECTION,
|
||||
* - RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE, and
|
||||
* - RFCOMM_EVENT_CHANNEL_CLOSED
|
||||
*/
|
||||
|
||||
/* LISTING_START(SppServerPacketHandler): SPP Server - Heartbeat Counter over RFCOMM */
|
||||
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
/* LISTING_PAUSE */
|
||||
bd_addr_t event_addr;
|
||||
uint8_t rfcomm_channel_nr;
|
||||
uint16_t mtu;
|
||||
int i;
|
||||
|
||||
switch (packet_type) {
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (packet[0]) {
|
||||
|
||||
case BTSTACK_EVENT_STATE:
|
||||
// BTstack activated, get started
|
||||
if (packet[2] == HCI_STATE_WORKING) {
|
||||
printf("BTstack is up and running\n");
|
||||
}
|
||||
break;
|
||||
/* LISTING_RESUME */
|
||||
/* @text Upon receiving HCI_EVENT_PIN_CODE_REQUEST event, we need to handle
|
||||
* authentication. Here, we use a fixed PIN code "0000".
|
||||
*/
|
||||
case HCI_EVENT_PIN_CODE_REQUEST:
|
||||
// pre-ssp: inform about pin code request
|
||||
printf("Pin code request - using '0000'\n");
|
||||
bt_flip_addr(event_addr, &packet[2]);
|
||||
hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
|
||||
break;
|
||||
|
||||
/* @text When HCI_EVENT_USER_CONFIRMATION_REQUEST is received, the user will be
|
||||
* asked to accept the pairing request. If the IO capability is set to
|
||||
* SSP_IO_CAPABILITY_DISPLAY_YES_NO, the request will be automatically accepted.
|
||||
*/
|
||||
case HCI_EVENT_USER_CONFIRMATION_REQUEST:
|
||||
// ssp: inform about user confirmation request
|
||||
printf("SSP User Confirmation Request with numeric value '%06u'\n", READ_BT_32(packet, 8));
|
||||
printf("SSP User Confirmation Auto accept\n");
|
||||
break;
|
||||
|
||||
/* @text The RFCOMM_EVENT_INCOMING_CONNECTION event indicates an incoming connection.
|
||||
* Here, the connection is accepted. More logic is need, if you want to handle connections
|
||||
* from multiple clients. The incoming RFCOMM connection event contains the RFCOMM
|
||||
* channel number used during the SPP setup phase and the newly assigned RFCOMM
|
||||
* channel ID that is used by all BTstack commands and events.
|
||||
*/
|
||||
case RFCOMM_EVENT_INCOMING_CONNECTION:
|
||||
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
|
||||
bt_flip_addr(event_addr, &packet[2]);
|
||||
rfcomm_channel_nr = packet[8];
|
||||
rfcomm_channel_id = READ_BT_16(packet, 9);
|
||||
printf("RFCOMM channel %u requested for %s\n", rfcomm_channel_nr, bd_addr_to_str(event_addr));
|
||||
rfcomm_accept_connection_internal(rfcomm_channel_id);
|
||||
break;
|
||||
|
||||
/* @text If RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE event returns status greater then 0,
|
||||
* then the channel establishment has failed (rare case, e.g., client crashes).
|
||||
* On successful connection, the RFCOMM channel ID and MTU for this
|
||||
* channel are made available to the heartbeat counter. After openning the RFCOMM channel,
|
||||
* the communication between client and the application
|
||||
* takes place. In this example, the timer handler increases the real counter every
|
||||
* second.
|
||||
*/
|
||||
|
||||
case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
|
||||
// data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
|
||||
if (packet[2]) {
|
||||
printf("RFCOMM channel open failed, status %u\n", packet[2]);
|
||||
} else {
|
||||
rfcomm_channel_id = READ_BT_16(packet, 12);
|
||||
mtu = READ_BT_16(packet, 14);
|
||||
printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu);
|
||||
}
|
||||
break;
|
||||
/* LISTING_PAUSE */
|
||||
case RFCOMM_EVENT_CHANNEL_CLOSED:
|
||||
printf("RFCOMM channel closed\n");
|
||||
rfcomm_channel_id = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RFCOMM_DATA_PACKET:
|
||||
printf("RCV: '");
|
||||
for (i=0;i<size;i++){
|
||||
putchar(packet[i]);
|
||||
}
|
||||
printf("'\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* LISTING_RESUME */
|
||||
}
|
||||
/* LISTING_END */
|
||||
|
||||
int btstack_main(int argc, const char * argv[]);
|
||||
int btstack_main(int argc, const char * argv[]){
|
||||
// set one-shot timer
|
||||
heartbeat.process = &heartbeat_handler;
|
||||
run_loop_set_timer(&heartbeat, HEARTBEAT_PERIOD_MS);
|
||||
run_loop_add_timer(&heartbeat);
|
||||
|
||||
spp_service_setup();
|
||||
|
||||
hci_discoverable_control(1);
|
||||
hci_ssp_set_io_capability(SSP_IO_CAPABILITY_DISPLAY_YES_NO);
|
||||
gap_set_local_name("BTstack SPP Counter");
|
||||
|
||||
// turn on!
|
||||
hci_power_control(HCI_POWER_ON);
|
||||
|
||||
hci_power_control(HCI_POWER_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* EXAMPLE_END */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user