Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (4.871 KB)

1 58fe0e0b Thomas Schöpping
#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 f8cf404d Thomas Schöpping
#include <global.hpp>
10
11 58fe0e0b Thomas Schöpping
using namespace chibios_rt;
12
using namespace amiro;
13
14 f8cf404d Thomas Schöpping
extern Global global;
15
16 58fe0e0b Thomas Schöpping
/*
17
 * Class constructor
18
 */
19
BluetoothIwrap::BluetoothIwrap(UARTDriver* uart) :
20
  BaseStaticThread<128>(), transport(uart), profiles{},
21
  mailbox(mailboxBuffer, BLUETOOTH_IWRAP_MAILBOX_SIZE), connAddr{0} {
22
  iwrapblock = 0;
23
}
24
25
//----------------------------------------------------------------
26
27
msg_t BluetoothIwrap::main(void) {
28
  setName("BluetoothIwrap");
29
30
  // To set the receive mailbox[9] for plain communication (WT12->host)
31
  transport.bluetoothTransportSetReceiveMailbox(HOST_IWRAP_PLAIN_LINKID, &this->mailbox);
32
33
  transport.start(NORMALPRIO);
34
35
  while (!this->shouldTerminate()) {
36
    iwrapReceive();
37
  }
38
  return RDY_OK;
39
}
40
41
/*
42
 * Member functions
43
 */
44
msg_t BluetoothIwrap::iwrapReceive() {
45
  BluetoothDescriptor* descriptor = NULL;
46
  const char* buffer;
47
  size_t length;
48
  msg_t msg;
49
50
  msg = mailbox.fetch((msg_t*) &descriptor, TIME_INFINITE);
51
  if (msg == RDY_RESET)
52
    return RDY_RESET;
53
54
  buffer = (const char*)descriptor->bluetoothDescriptorGetPayload();
55
  length = descriptor->bluetoothDescriptorGetPayloadLength();
56
57
  for (size_t i = 0; i < length; i++) {
58
    // print out received chars
59 f8cf404d Thomas Schöpping
    chSequentialStreamPut((BaseSequentialStream*) &global.sercanmux1, buffer[i]);
60 58fe0e0b Thomas Schöpping
  }
61
62
  // reset block
63
  iwrapblock = 0;
64
65
  // if RING or CONNECT event is received, then look for profile with correct MAC-address and connect.
66
  if (strstr(buffer, "CONNECT ") && (strstr(buffer, " RFCOMM 1") || strstr(buffer, " L2CAP 1"))) {
67
  // if CONNECT event serial RFCOMM 1 or wiimote (control) L2CAP 11 or wiimote (data) L2CAP 13
68
    for (int i = 0; i < 8; i++) {
69
      if ((profiles[i].addr != NULL) && strstr(connAddr, profiles[i].addr)) {
70
        BluetoothProfile* bp =  &(profiles[i]);
71
        bp->linkid = buffer[8] - '0';     // look for linkid and convert linkid to int
72
        (((BluetoothConnector*)(bp->connector))->*(bp->connect))(bp->linkid);
73
        break;
74
      }
75
    }
76
  } else if (strstr(buffer, "RING") && strstr(buffer, "1 RFCOMM ")) {
77
  // if RING event (be called by other device) in 1 RFCOMM mode
78
    for (int i = 0; i < 8; i++) {
79
      if ((profiles[i].addr != NULL) && (strstr(buffer, profiles[i].addr) || strstr(profiles[i].addr, "free"))) {
80
        BluetoothProfile* bp =  &(profiles[i]);
81
        bp->linkid  = buffer[5] - '0';    // look for linkid and convert linkid to int
82
        (((BluetoothConnector*)(bp->connector))->*(bp->connect))(bp->linkid );
83
        break;
84
      }
85
    }
86
  } else if (strstr(buffer, "NO CARRIER ") && strstr(buffer, "ERROR ")) {
87
  // if NO CARRIER ERROR 0 event, then look for profile and disconnect
88
    uint8_t linkid = buffer[11] - '0';
89
    for (int i = 0; i < 8; i++) {
90
      if ((profiles[i].addr != NULL) && (profiles[i].linkid == linkid)) {
91
        BluetoothProfile* bp =  &(profiles[i]);
92
        bp->linkid = 0xFF;
93
        (((BluetoothConnector*)(bp->connector))->*(bp->disconnect))();
94
        break;
95
      }
96
    }
97
  }
98
99
  msg = (transport.bluetoothTransportGetStorageMailbox())->post((msg_t) descriptor, TIME_INFINITE);
100
  if (msg == RDY_RESET)
101
    return RDY_RESET;
102
103
  return RDY_OK;
104
}
105
106
msg_t BluetoothIwrap::iwrapTransmit(uint8_t linkid, const uint8_t* txdata, size_t length) {
107
  BluetoothDescriptor* descriptor = NULL;
108
  uint8_t *buffer;
109
  msg_t msg;
110
111
  msg = transport.bluetoothTransportGetStorageMailbox()->fetch((msg_t*) &descriptor, TIME_INFINITE);
112
  if (msg == RDY_RESET)
113
    return RDY_RESET;
114
115
  buffer = descriptor->bluetoothDescriptorGetPayload();
116
  memcpy(buffer, txdata, length);
117
118
  descriptor->bluetoothDescriptorSetLinkId(linkid);
119
  descriptor->bluetoothDescriptorSetPayloadLength(length);
120
121
  msg = transport.bluetoothTransportGetTransmitMailbox()->post((msg_t) descriptor, TIME_INFINITE);
122
  if (msg == RDY_RESET)
123
    return RDY_RESET;
124
125
  return RDY_OK;
126
}
127
128
void BluetoothIwrap::bluetoothIwrapSendCommand(const char* cmd) {
129
  // Wait until another previous command finished.
130
  while(iwrapblock == 1) {
131
    BaseThread::sleep(MS2ST(500));
132
  }
133
134
  iwrapblock = 1;
135
136
  if (strstr(cmd, "CALL ") && (strstr(cmd, " RFCOMM") || strstr(cmd, " L2CAP"))) {
137
    memcpy(connAddr, cmd+5, 17);
138
  }
139
140
  size_t length = strlen(cmd);
141
//  for (size_t i = 0; i < length; i++)
142 f8cf404d Thomas Schöpping
//    chSequentialStreamPut((BaseSequentialStream*) &global.sercanmux1, cmd[i]);   // To display the command
143 58fe0e0b Thomas Schöpping
144
  // To send the string command to WT12 bluetooth chip
145
  iwrapTransmit(HOST_IWRAP_PLAIN_LINKID,(uint8_t*) cmd, length);
146
147
  // Clear iwrapblock flag because these commands don't return an answer
148
  if(strstr(cmd, "SET BT NAME") || strstr(cmd, "SET BT AUTH") || strstr(cmd, "SET BT SSP")
149
    || strstr(cmd, "SET BT PAGEMODE") || strstr(cmd, "SET BT PAIR *")
150
    || strstr(cmd, "SET CONTROL MUX") || (strstr(cmd, "SET") && strlen(cmd) == 3)) {
151
    iwrapblock = 0;
152
  }
153
154
  BaseThread::sleep(MS2ST(500));
155
}