#include <stdio.h>
#include <string.h>
#include <io.h>
#include <stdlib.h>
#include <dev/usart.h>
#include <dev/usartavr.h>
#include <bt/bt_hci_cmds.h>
#include <bt/bt_l2cap.h>
#include <bt/bt_rfcomm.h>
#include <terminal/btn-terminal.h>
#include <terminal/btn-cmds.h>
#include <terminal/bt-cmds.h>
#include <terminal/nut-cmds.h>
#include <terminal/l2cap-cmds.h>
#include <terminal/rfcomm-cmds.h>
#include <led/btn-led.h>
#include <hardware/btn-hardware.h>
#include <sys/timer.h>

#define BT_L2CAP_HCI_PACKET_TYPE         (BT_HCI_PACKET_TYPE_DM1 | BT_HCI_PACKET_TYPE_DH1 | \
                                          BT_HCI_PACKET_TYPE_DM3 | BT_HCI_PACKET_TYPE_DH3)

#define MIN_CREDITS 10
#define MAX_CREDITS 40

void rcv_cb(u_char dlci, u_char * payload, u_short len, void *arg)
{
    u_short idx;
    if (len > 0) {
        printf("\n");
        for (idx = 0; idx < len; idx++)
            printf("%c ", payload[idx]);
    }
}

void con_cb(u_char dlci, u_char type, void *arg)
{
    if (type == BT_RFCOMM_CONNECT) {
        printf("RFCOMM Connect on dlci %d...\n", dlci);
        bt_rfcomm_send_credits(dlci, MAX_CREDITS - BT_RFCOMM_DEF_CREDITS);
    } else {
        printf("RFCOMM Disconnect on dlci %d...\n", dlci);
    }
}

void line_cb(u_char dlci, u_char flags, void *arg)
{
    printf("rfcomm Line status has changed: dlci: %d, flags: %02x\n", dlci, flags);
}

void credit_cb(u_char dlci, u_char credits, void *arg)
{
    printf("rfcomm Credits running low for dlci %d. Credits remaining: %d\n", dlci, credits);
    printf("rfcomm Send new credits: %d\n", MAX_CREDITS - credits);
    bt_rfcomm_send_credits(dlci, MAX_CREDITS - credits);
}

FILE   *uart_terminal;
struct btstack* stack;
struct bt_l2cap_stack* l2cap_stack;
struct bt_rfcomm_stack* rfcomm_stack;

void send_at(char* arg) {
    // address of device (reverse order!)
    bt_addr_t BTaddress = { 0xc5, 0xe1, 0x61, 0xde, 0x0f, 0x00 };

    printf("starting session...\n");
    if (bt_rfcomm_start_session(BTaddress, 0, 0)) {
        printf("session error.\n");
        return;
    }
    NutSleep(1000);
    printf("connecting...\n");
    if (bt_rfcomm_connect(1, con_cb, rcv_cb, line_cb, credit_cb, 10, NULL)) {
        printf("connection error.\n");
        return;
    }
    NutSleep(1000);

    printf("sending command...\n");
    // send commands using bt_rfcomm_send(u_char dlci, u_char *message, u_short length)
    // don't forget NutSleep() after each command!

    printf("Disconnect.\n");
    bt_rfcomm_disconnect(2);
}

/**
 * main function that initializes the hardware, led, terminal, bluetooth
 * and acl communication stack and registers some predefined commands.
 * Use tab-tab to see the registered commands once the program is running.
 */
int main(void)
{
    // serial baud rate
    u_long baud = 57600;

    // hardware init
    btn_hardware_init();
    btn_led_init(1);

    // init app uart
    NutRegisterDevice(&APP_UART, 0, 0);
    freopen(APP_UART.dev_name, "r+", stdout);
    _ioctl(_fileno(stdout), UART_SETSPEED, &baud);

    // hello world!
    printf_P(PSTR("\n# --------------------------------------------"));
    printf_P(PSTR("\n# Welcome to BTnut (c) 2009 ETH Zurich\n"));
    printf_P(PSTR("# rfcomm-cmd\n"));
    printf_P(PSTR("# --------------------------------------------"));
    printf_P(PSTR("\nbooting bluetooth module... "));

    // bluetooth module on (takes a while)
    btn_hardware_bt_on();

    // verbose debug of all hci information
    //_bt_hci_debug_uart = 1;

    // Start the stack and let the initialization begin
    stack = bt_hci_init(&BT_UART);
    bt_hci_write_local_cod(stack, BT_HCI_SYNC, 200);
    printf_P(PSTR("ok.\n\r"));

    // give hint
    printf_P(PSTR("hit tab twice for a list of commands\n\r"));

    // terminal init
    btn_terminal_init(stdout, "[rfcomm-cmd]$");
    bt_cmds_init(stack);

    // Start L2CAP and RFCOMM
    l2cap_stack = bt_l2cap_init(stack, 8, 8, BT_L2CAP_HCI_PACKET_TYPE);
    l2cap_cmds_init(l2cap_stack, 1, BT_L2CAP_MIN_MTU, BT_L2CAP_MTU_DEFAULT);

    rfcomm_stack = bt_rfcomm_init(l2cap_stack, BT_RFCOMM_DEF_MFS, 4, 5);
    rfcomm_cmds_init();

    bt_cmds_register_cmds();
    btn_cmds_register_cmds();
    nut_cmds_register_cmds();
    l2cap_cmds_register_cmds();
    rfcomm_cmds_register_cmds();
    btn_terminal_register_cmd("send_at", send_at);

    // terminal mode
    btn_terminal_run(BTN_TERMINAL_NOFORK, 0);
    return 0;
}
!!! Dieses Dokument stammt aus dem ETH Web-Archiv und wird nicht mehr gepflegt !!!
!!! This document is stored in the ETH Web archive and is no longer maintained !!!