amiro-os / components / bluetooth / bluetooth-iwrap.cpp @ 4d54a507
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 | } |