Statistics
| Branch: | Tag: | Revision:

amiro-os / components / bluetooth / bluetooth-iwrap.cpp @ 10687985

History | View | Annotate | Download (4.799 KB)

1
#include <ch.hpp>
2
#include <hal.h>
3

    
4
#include <string.h>
5

    
6
#include <amiro/bluetooth/bluetooth-iwrap.hpp>
7
#include <amiro/bluetooth/bluetooth-connector.hpp>
8

    
9
using namespace chibios_rt;
10
using namespace amiro;
11

    
12
/*
13
 * Class constructor
14
 */
15
BluetoothIwrap::BluetoothIwrap(UARTDriver* uart) :
16
  BaseStaticThread<128>(), transport(uart), profiles{},
17
  mailbox(mailboxBuffer, BLUETOOTH_IWRAP_MAILBOX_SIZE), connAddr{0} {
18
  iwrapblock = 0;
19
}
20

    
21
//----------------------------------------------------------------
22

    
23
msg_t BluetoothIwrap::main(void) {
24
  setName("BluetoothIwrap");
25

    
26
  // To set the receive mailbox[9] for plain communication (WT12->host)
27
  transport.bluetoothTransportSetReceiveMailbox(HOST_IWRAP_PLAIN_LINKID, &this->mailbox);
28

    
29
  transport.start(NORMALPRIO);
30

    
31
  while (!this->shouldTerminate()) {
32
    iwrapReceive();
33
  }
34
  return RDY_OK;
35
}
36

    
37
/*
38
 * Member functions
39
 */
40
msg_t BluetoothIwrap::iwrapReceive() {
41
  BluetoothDescriptor* descriptor = NULL;
42
  const char* buffer;
43
  size_t length;
44
  msg_t msg;
45

    
46
  msg = mailbox.fetch((msg_t*) &descriptor, TIME_INFINITE);
47
  if (msg == RDY_RESET)
48
    return RDY_RESET;
49

    
50
  buffer = (const char*)descriptor->bluetoothDescriptorGetPayload();
51
  length = descriptor->bluetoothDescriptorGetPayloadLength();
52

    
53
  for (size_t i = 0; i < length; i++) {
54
    // print out received chars
55
    chSequentialStreamPut((BaseSequentialStream*) &SD1, buffer[i]);
56
  }
57

    
58
  // reset block
59
  iwrapblock = 0;
60

    
61
  // if RING or CONNECT event is received, then look for profile with correct MAC-address and connect.
62
  if (strstr(buffer, "CONNECT ") && (strstr(buffer, " RFCOMM 1") || strstr(buffer, " L2CAP 1"))) {
63
  // if CONNECT event serial RFCOMM 1 or wiimote (control) L2CAP 11 or wiimote (data) L2CAP 13
64
    for (int i = 0; i < 8; i++) {
65
      if ((profiles[i].addr != NULL) && strstr(connAddr, profiles[i].addr)) {
66
        BluetoothProfile* bp =  &(profiles[i]);
67
        bp->linkid = buffer[8] - '0';     // look for linkid and convert linkid to int
68
        (((BluetoothConnector*)(bp->connector))->*(bp->connect))(bp->linkid);
69
        break;
70
      }
71
    }
72
  } else if (strstr(buffer, "RING") && strstr(buffer, "1 RFCOMM ")) {
73
  // if RING event (be called by other device) in 1 RFCOMM mode
74
    for (int i = 0; i < 8; i++) {
75
      if ((profiles[i].addr != NULL) && (strstr(buffer, profiles[i].addr) || strstr(profiles[i].addr, "free"))) {
76
        BluetoothProfile* bp =  &(profiles[i]);
77
        bp->linkid  = buffer[5] - '0';    // look for linkid and convert linkid to int
78
        (((BluetoothConnector*)(bp->connector))->*(bp->connect))(bp->linkid );
79
        break;
80
      }
81
    }
82
  } else if (strstr(buffer, "NO CARRIER ") && strstr(buffer, "ERROR ")) {
83
  // if NO CARRIER ERROR 0 event, then look for profile and disconnect
84
    uint8_t linkid = buffer[11] - '0';
85
    for (int i = 0; i < 8; i++) {
86
      if ((profiles[i].addr != NULL) && (profiles[i].linkid == linkid)) {
87
        BluetoothProfile* bp =  &(profiles[i]);
88
        bp->linkid = 0xFF;
89
        (((BluetoothConnector*)(bp->connector))->*(bp->disconnect))();
90
        break;
91
      }
92
    }
93
  }
94

    
95
  msg = (transport.bluetoothTransportGetStorageMailbox())->post((msg_t) descriptor, TIME_INFINITE);
96
  if (msg == RDY_RESET)
97
    return RDY_RESET;
98

    
99
  return RDY_OK;
100
}
101

    
102
msg_t BluetoothIwrap::iwrapTransmit(uint8_t linkid, const uint8_t* txdata, size_t length) {
103
  BluetoothDescriptor* descriptor = NULL;
104
  uint8_t *buffer;
105
  msg_t msg;
106

    
107
  msg = transport.bluetoothTransportGetStorageMailbox()->fetch((msg_t*) &descriptor, TIME_INFINITE);
108
  if (msg == RDY_RESET)
109
    return RDY_RESET;
110

    
111
  buffer = descriptor->bluetoothDescriptorGetPayload();
112
  memcpy(buffer, txdata, length);
113

    
114
  descriptor->bluetoothDescriptorSetLinkId(linkid);
115
  descriptor->bluetoothDescriptorSetPayloadLength(length);
116

    
117
  msg = transport.bluetoothTransportGetTransmitMailbox()->post((msg_t) descriptor, TIME_INFINITE);
118
  if (msg == RDY_RESET)
119
    return RDY_RESET;
120

    
121
  return RDY_OK;
122
}
123

    
124
void BluetoothIwrap::bluetoothIwrapSendCommand(const char* cmd) {
125
  // Wait until another previous command finished.
126
  while(iwrapblock == 1) {
127
    BaseThread::sleep(MS2ST(500));
128
  }
129

    
130
  iwrapblock = 1;
131

    
132
  if (strstr(cmd, "CALL ") && (strstr(cmd, " RFCOMM") || strstr(cmd, " L2CAP"))) {
133
    memcpy(connAddr, cmd+5, 17);
134
  }
135

    
136
  size_t length = strlen(cmd);
137
//  for (size_t i = 0; i < length; i++)
138
//    chSequentialStreamPut((BaseSequentialStream*) &SD1, cmd[i]);   // To display the command
139

    
140
  // To send the string command to WT12 bluetooth chip
141
  iwrapTransmit(HOST_IWRAP_PLAIN_LINKID,(uint8_t*) cmd, length);
142

    
143
  // Clear iwrapblock flag because these commands don't return an answer
144
  if(strstr(cmd, "SET BT NAME") || strstr(cmd, "SET BT AUTH") || strstr(cmd, "SET BT SSP")
145
    || strstr(cmd, "SET BT PAGEMODE") || strstr(cmd, "SET BT PAIR *")
146
    || strstr(cmd, "SET CONTROL MUX") || (strstr(cmd, "SET") && strlen(cmd) == 3)) {
147
    iwrapblock = 0;
148
  }
149

    
150
  BaseThread::sleep(MS2ST(500));
151
}