Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (4.871 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
#include <global.hpp>
10

    
11
using namespace chibios_rt;
12
using namespace amiro;
13

    
14
extern Global global;
15

    
16
/*
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
    chSequentialStreamPut((BaseSequentialStream*) &global.sercanmux1, buffer[i]);
60
  }
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
//    chSequentialStreamPut((BaseSequentialStream*) &global.sercanmux1, cmd[i]);   // To display the command
143

    
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
}