ロボコンマガジン 2013年1月号に掲載されている 「第3回お手軽mbedではじめるロボットプロトタイピング」 で紹介しているうおーるぼっとをマウスで動かすプログラムです。

Dependencies:   FatFileSystem TB6612FNG2 mbed

Fork of BlueUSB by Peter Barrett

Committer:
jksoft
Date:
Fri Dec 14 03:34:00 2012 +0000
Revision:
1:2526b2c89256
Parent:
0:606b230e5b4a
Rev1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
peterbarrett1967 0:606b230e5b4a 1
peterbarrett1967 0:606b230e5b4a 2 /*
peterbarrett1967 0:606b230e5b4a 3 Copyright (c) 2010 Peter Barrett
peterbarrett1967 0:606b230e5b4a 4
peterbarrett1967 0:606b230e5b4a 5 Permission is hereby granted, free of charge, to any person obtaining a copy
peterbarrett1967 0:606b230e5b4a 6 of this software and associated documentation files (the "Software"), to deal
peterbarrett1967 0:606b230e5b4a 7 in the Software without restriction, including without limitation the rights
peterbarrett1967 0:606b230e5b4a 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
peterbarrett1967 0:606b230e5b4a 9 copies of the Software, and to permit persons to whom the Software is
peterbarrett1967 0:606b230e5b4a 10 furnished to do so, subject to the following conditions:
peterbarrett1967 0:606b230e5b4a 11
peterbarrett1967 0:606b230e5b4a 12 The above copyright notice and this permission notice shall be included in
peterbarrett1967 0:606b230e5b4a 13 all copies or substantial portions of the Software.
peterbarrett1967 0:606b230e5b4a 14
peterbarrett1967 0:606b230e5b4a 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
peterbarrett1967 0:606b230e5b4a 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
peterbarrett1967 0:606b230e5b4a 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
peterbarrett1967 0:606b230e5b4a 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
peterbarrett1967 0:606b230e5b4a 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
peterbarrett1967 0:606b230e5b4a 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
peterbarrett1967 0:606b230e5b4a 21 THE SOFTWARE.
peterbarrett1967 0:606b230e5b4a 22 */
peterbarrett1967 0:606b230e5b4a 23
peterbarrett1967 0:606b230e5b4a 24 #include <stdio.h>
peterbarrett1967 0:606b230e5b4a 25 #include <stdlib.h>
peterbarrett1967 0:606b230e5b4a 26 #include <stdio.h>
peterbarrett1967 0:606b230e5b4a 27 #include <string.h>
peterbarrett1967 0:606b230e5b4a 28
peterbarrett1967 0:606b230e5b4a 29 #include "Utils.h"
peterbarrett1967 0:606b230e5b4a 30 #include "hci.h"
peterbarrett1967 0:606b230e5b4a 31 #include "hci_private.h"
peterbarrett1967 0:606b230e5b4a 32
peterbarrett1967 0:606b230e5b4a 33 enum hci_callback_evt
peterbarrett1967 0:606b230e5b4a 34 {
peterbarrett1967 0:606b230e5b4a 35 NONE,
peterbarrett1967 0:606b230e5b4a 36 CONNECT,
peterbarrett1967 0:606b230e5b4a 37 DISCONECT,
peterbarrett1967 0:606b230e5b4a 38 INQUIRYRESULT
peterbarrett1967 0:606b230e5b4a 39 };
peterbarrett1967 0:606b230e5b4a 40
peterbarrett1967 0:606b230e5b4a 41 #define MAX_BLUETOOTH_ADAPTERS 1
peterbarrett1967 0:606b230e5b4a 42
peterbarrett1967 0:606b230e5b4a 43 enum StateMask {
peterbarrett1967 0:606b230e5b4a 44 MASK_RESET = 1,
peterbarrett1967 0:606b230e5b4a 45 MASK_READ_BUFFER_SIZE = 2,
peterbarrett1967 0:606b230e5b4a 46 MASK_READ_BD_ADDR = 4,
peterbarrett1967 0:606b230e5b4a 47 MASK_INITED = 8,
peterbarrett1967 0:606b230e5b4a 48 MASK_INQUIRY = 16,
peterbarrett1967 0:606b230e5b4a 49 MASK_REMOTE_NAME = 32,
peterbarrett1967 0:606b230e5b4a 50 MASK_CREATE_CONNECTION = 64
peterbarrett1967 0:606b230e5b4a 51 };
peterbarrett1967 0:606b230e5b4a 52
peterbarrett1967 0:606b230e5b4a 53 int HCI::Open(HCITransport* transport, HCICallback callback)
peterbarrett1967 0:606b230e5b4a 54 {
peterbarrett1967 0:606b230e5b4a 55 _transport = transport;
peterbarrett1967 0:606b230e5b4a 56 _transport->Set(this);
peterbarrett1967 0:606b230e5b4a 57 _callback = callback;
peterbarrett1967 0:606b230e5b4a 58 _state = 0;
peterbarrett1967 0:606b230e5b4a 59 for (int i = 0; i < MAX_BTDEVICES; i++)
peterbarrett1967 0:606b230e5b4a 60 {
peterbarrett1967 0:606b230e5b4a 61 _devices[i].Init();
peterbarrett1967 0:606b230e5b4a 62 _devices[i]._transport = transport;
peterbarrett1967 0:606b230e5b4a 63 }
peterbarrett1967 0:606b230e5b4a 64 return SendCmd(HCI_OP_RESET);
peterbarrett1967 0:606b230e5b4a 65 }
peterbarrett1967 0:606b230e5b4a 66
peterbarrett1967 0:606b230e5b4a 67 void printf(const BD_ADDR* addr);
peterbarrett1967 0:606b230e5b4a 68
peterbarrett1967 0:606b230e5b4a 69 BTDevice* HCI::Find(const BD_ADDR* addr)
peterbarrett1967 0:606b230e5b4a 70 {
peterbarrett1967 0:606b230e5b4a 71 for (int i = 0; i < MAX_BTDEVICES; i++)
peterbarrett1967 0:606b230e5b4a 72 if (_devices[i]._state != 0 && memcmp(addr,&_devices[i]._info.bdaddr,6) == 0)
peterbarrett1967 0:606b230e5b4a 73 return &_devices[i];
peterbarrett1967 0:606b230e5b4a 74 return 0;
peterbarrett1967 0:606b230e5b4a 75 }
peterbarrett1967 0:606b230e5b4a 76
peterbarrett1967 0:606b230e5b4a 77 BTDevice* HCI::Find(int handle)
peterbarrett1967 0:606b230e5b4a 78 {
peterbarrett1967 0:606b230e5b4a 79 for (int i = 0; i < MAX_BTDEVICES; i++)
peterbarrett1967 0:606b230e5b4a 80 if (_devices[i]._state != 0 && handle == _devices[i]._handle)
peterbarrett1967 0:606b230e5b4a 81 return &_devices[i];
peterbarrett1967 0:606b230e5b4a 82 return 0;
peterbarrett1967 0:606b230e5b4a 83 }
peterbarrett1967 0:606b230e5b4a 84 //
peterbarrett1967 0:606b230e5b4a 85 bool HCI::Busy()
peterbarrett1967 0:606b230e5b4a 86 {
peterbarrett1967 0:606b230e5b4a 87 return (_state & (MASK_INQUIRY | MASK_REMOTE_NAME | MASK_CREATE_CONNECTION)) != 0;
peterbarrett1967 0:606b230e5b4a 88 }
peterbarrett1967 0:606b230e5b4a 89
peterbarrett1967 0:606b230e5b4a 90 int HCI::Inquiry(int duration)
peterbarrett1967 0:606b230e5b4a 91 {
peterbarrett1967 0:606b230e5b4a 92 _state |= MASK_INQUIRY;
peterbarrett1967 0:606b230e5b4a 93 u8 buf[5];
peterbarrett1967 0:606b230e5b4a 94 buf[0] = 0x33;
peterbarrett1967 0:606b230e5b4a 95 buf[1] = 0x8B;
peterbarrett1967 0:606b230e5b4a 96 buf[2] = 0x9E;
peterbarrett1967 0:606b230e5b4a 97 buf[3] = duration;
peterbarrett1967 0:606b230e5b4a 98 buf[4] = 5; // 5 results
peterbarrett1967 0:606b230e5b4a 99 SendCmd(HCI_OP_INQUIRY,buf,sizeof(buf));
peterbarrett1967 0:606b230e5b4a 100 return 0;
peterbarrett1967 0:606b230e5b4a 101 }
peterbarrett1967 0:606b230e5b4a 102
peterbarrett1967 0:606b230e5b4a 103 int HCI::SendCmd(int cmd, const u8* params, int len)
peterbarrett1967 0:606b230e5b4a 104 {
peterbarrett1967 0:606b230e5b4a 105 u8 b[32];
peterbarrett1967 0:606b230e5b4a 106 b[0] = cmd;
peterbarrett1967 0:606b230e5b4a 107 b[1] = (cmd >> 8);
peterbarrett1967 0:606b230e5b4a 108 b[2] = len;
peterbarrett1967 0:606b230e5b4a 109 if (params)
peterbarrett1967 0:606b230e5b4a 110 memcpy(b+3,params,len);
peterbarrett1967 0:606b230e5b4a 111 _transport->HCISend(b,len+3);
peterbarrett1967 0:606b230e5b4a 112 return 0;
peterbarrett1967 0:606b230e5b4a 113 }
peterbarrett1967 0:606b230e5b4a 114
peterbarrett1967 0:606b230e5b4a 115 void HCI::OnCommandComplete(int cmd, const u8* data, int len)
peterbarrett1967 0:606b230e5b4a 116 {
peterbarrett1967 0:606b230e5b4a 117 // printf("%04X %s",cmd,CmdStr(cmd));
peterbarrett1967 0:606b230e5b4a 118 if (len < 0)
peterbarrett1967 0:606b230e5b4a 119 return;
peterbarrett1967 0:606b230e5b4a 120 //printfBytes(" complete",data,min(16,len));
peterbarrett1967 0:606b230e5b4a 121
peterbarrett1967 0:606b230e5b4a 122 switch (cmd)
peterbarrett1967 0:606b230e5b4a 123 {
peterbarrett1967 0:606b230e5b4a 124 // Init phase 0
peterbarrett1967 0:606b230e5b4a 125 case HCI_OP_RESET: // Reset done, init chain to HCI_OP_READ_LOCAL_NAME
peterbarrett1967 0:606b230e5b4a 126 SendCmd(HCI_OP_READ_BUFFER_SIZE);
peterbarrett1967 0:606b230e5b4a 127 _state |= MASK_RESET;
peterbarrett1967 0:606b230e5b4a 128 break;
peterbarrett1967 0:606b230e5b4a 129
peterbarrett1967 0:606b230e5b4a 130 // Init phase 1
peterbarrett1967 0:606b230e5b4a 131 case HCI_OP_READ_BUFFER_SIZE:
peterbarrett1967 0:606b230e5b4a 132 _acl_mtu = LE16(data);
peterbarrett1967 0:606b230e5b4a 133 _sco_mtu = data[2];
peterbarrett1967 0:606b230e5b4a 134 _acl_max_pkt = LE16(data+3);
peterbarrett1967 0:606b230e5b4a 135 _sco_max_pkt = LE16(data+5);
peterbarrett1967 0:606b230e5b4a 136 SendCmd(HCI_OP_READ_BD_ADDR);
peterbarrett1967 0:606b230e5b4a 137 _state |= MASK_READ_BUFFER_SIZE;
peterbarrett1967 0:606b230e5b4a 138 break;
peterbarrett1967 0:606b230e5b4a 139
peterbarrett1967 0:606b230e5b4a 140 // Init phase 2
peterbarrett1967 0:606b230e5b4a 141 case HCI_OP_READ_BD_ADDR:
peterbarrett1967 0:606b230e5b4a 142 _localAddr = *((BD_ADDR*)data); // Local Address
peterbarrett1967 0:606b230e5b4a 143 _state |= MASK_READ_BD_ADDR;
peterbarrett1967 0:606b230e5b4a 144 _state |= MASK_INITED;
peterbarrett1967 0:606b230e5b4a 145 Callback(CALLBACK_READY,data,6);
peterbarrett1967 0:606b230e5b4a 146 break;
peterbarrett1967 0:606b230e5b4a 147
peterbarrett1967 0:606b230e5b4a 148 // 0CXX
peterbarrett1967 0:606b230e5b4a 149 case HCI_OP_READ_LOCAL_NAME:
peterbarrett1967 0:606b230e5b4a 150 break;
peterbarrett1967 0:606b230e5b4a 151
peterbarrett1967 0:606b230e5b4a 152 case HCI_OP_READ_LOCAL_VERSION:
peterbarrett1967 0:606b230e5b4a 153 // params
peterbarrett1967 0:606b230e5b4a 154 //SendCmd(HCI_OP_READ_LOCAL_NAME);
peterbarrett1967 0:606b230e5b4a 155 break;
peterbarrett1967 0:606b230e5b4a 156
peterbarrett1967 0:606b230e5b4a 157 case HCI_OP_READ_LOCAL_COMMANDS:
peterbarrett1967 0:606b230e5b4a 158 break;
peterbarrett1967 0:606b230e5b4a 159
peterbarrett1967 0:606b230e5b4a 160 case HCI_OP_READ_LOCAL_FEATURES:
peterbarrett1967 0:606b230e5b4a 161 //SendCmd(HCI_OP_READ_LOCAL_VERSION);
peterbarrett1967 0:606b230e5b4a 162 break;
peterbarrett1967 0:606b230e5b4a 163
peterbarrett1967 0:606b230e5b4a 164 case HCI_OP_READ_LOCAL_EXT_FEATURES:
peterbarrett1967 0:606b230e5b4a 165 break;
peterbarrett1967 0:606b230e5b4a 166
peterbarrett1967 0:606b230e5b4a 167 case HCI_OP_PIN_CODE_REPLY:
peterbarrett1967 0:606b230e5b4a 168 printf("Got pin reply\n");
peterbarrett1967 0:606b230e5b4a 169 break;
peterbarrett1967 0:606b230e5b4a 170
peterbarrett1967 0:606b230e5b4a 171 default:
peterbarrett1967 0:606b230e5b4a 172 printf("Unrecognized Command %04X\n",cmd);
peterbarrett1967 0:606b230e5b4a 173 break;
peterbarrett1967 0:606b230e5b4a 174 }
peterbarrett1967 0:606b230e5b4a 175 }
peterbarrett1967 0:606b230e5b4a 176
peterbarrett1967 0:606b230e5b4a 177 void HCI::Callback(HCI_CALLBACK_EVENT c, const u8* data, int len)
peterbarrett1967 0:606b230e5b4a 178 {
peterbarrett1967 0:606b230e5b4a 179 _callback(this,c,data,len);
peterbarrett1967 0:606b230e5b4a 180 }
peterbarrett1967 0:606b230e5b4a 181
peterbarrett1967 0:606b230e5b4a 182 int HCI::RemoteNameRequest(const BD_ADDR* addr)
peterbarrett1967 0:606b230e5b4a 183 {
peterbarrett1967 0:606b230e5b4a 184 _state |= MASK_REMOTE_NAME;
peterbarrett1967 0:606b230e5b4a 185 u8 buf[6+4];
peterbarrett1967 0:606b230e5b4a 186 memset(buf,0,sizeof(buf));
peterbarrett1967 0:606b230e5b4a 187 memcpy(buf,addr,6);
peterbarrett1967 0:606b230e5b4a 188 buf[7] = 1;
peterbarrett1967 0:606b230e5b4a 189 return SendCmd(HCI_OP_REMOTE_NAME_REQ,buf,sizeof(buf));
peterbarrett1967 0:606b230e5b4a 190 }
peterbarrett1967 0:606b230e5b4a 191
peterbarrett1967 0:606b230e5b4a 192 int HCI::CreateConnection(const BD_ADDR* remoteAddr)
peterbarrett1967 0:606b230e5b4a 193 {
peterbarrett1967 0:606b230e5b4a 194 _state |= MASK_CREATE_CONNECTION;
peterbarrett1967 0:606b230e5b4a 195 u8 buf[6+7];
peterbarrett1967 0:606b230e5b4a 196 memset(buf,0,sizeof(buf));
peterbarrett1967 0:606b230e5b4a 197 memcpy(buf,remoteAddr,6);
peterbarrett1967 0:606b230e5b4a 198 buf[6] = 0x18; // DM1,DH1
peterbarrett1967 0:606b230e5b4a 199 buf[7] = 0xCC; // DM3, DH3, DM5, DH5
peterbarrett1967 0:606b230e5b4a 200 buf[8] = 1; // Page Repetition R1
peterbarrett1967 0:606b230e5b4a 201 return SendCmd(HCI_OP_CREATE_CONN,buf,sizeof(buf));
peterbarrett1967 0:606b230e5b4a 202 }
peterbarrett1967 0:606b230e5b4a 203
peterbarrett1967 0:606b230e5b4a 204 int HCI::Disconnect(const BD_ADDR* bdaddr)
peterbarrett1967 0:606b230e5b4a 205 {
peterbarrett1967 0:606b230e5b4a 206 BTDevice* d = Find(bdaddr);
peterbarrett1967 0:606b230e5b4a 207 if (!d)
peterbarrett1967 0:606b230e5b4a 208 return ERR_HCI_DEVICE_NOT_FOUND;
peterbarrett1967 0:606b230e5b4a 209 int handle = d->_handle;
peterbarrett1967 0:606b230e5b4a 210 printf("Disconnect from %d\n",handle);
peterbarrett1967 0:606b230e5b4a 211 _state |= MASK_CREATE_CONNECTION;
peterbarrett1967 0:606b230e5b4a 212 u8 buf[3];
peterbarrett1967 0:606b230e5b4a 213 buf[0] = handle;
peterbarrett1967 0:606b230e5b4a 214 buf[1] = (handle >> 8);
peterbarrett1967 0:606b230e5b4a 215 buf[2] = 0x13;
peterbarrett1967 0:606b230e5b4a 216 return SendCmd(HCI_OP_DISCONNECT,buf,sizeof(buf));
peterbarrett1967 0:606b230e5b4a 217 }
peterbarrett1967 0:606b230e5b4a 218
peterbarrett1967 0:606b230e5b4a 219 void HCI::DisconnectComplete(int handle)
peterbarrett1967 0:606b230e5b4a 220 {
peterbarrett1967 0:606b230e5b4a 221 BTDevice* d = Find(handle);
peterbarrett1967 0:606b230e5b4a 222 if (!d)
peterbarrett1967 0:606b230e5b4a 223 return;
peterbarrett1967 0:606b230e5b4a 224 d->_handle = 0;
peterbarrett1967 0:606b230e5b4a 225 }
peterbarrett1967 0:606b230e5b4a 226
peterbarrett1967 0:606b230e5b4a 227 int HCI::DisconnectAll()
peterbarrett1967 0:606b230e5b4a 228 {
peterbarrett1967 0:606b230e5b4a 229 BTDevice* devs[8];
peterbarrett1967 0:606b230e5b4a 230 int count = GetDevices(devs,8);
peterbarrett1967 0:606b230e5b4a 231 for (int i = 0; i < count; i++)
peterbarrett1967 0:606b230e5b4a 232 Disconnect(&devs[i]->_info.bdaddr);
peterbarrett1967 0:606b230e5b4a 233 return 0;
peterbarrett1967 0:606b230e5b4a 234 }
peterbarrett1967 0:606b230e5b4a 235
peterbarrett1967 0:606b230e5b4a 236 int HCI::PinCodeReply(const u8* data)
peterbarrett1967 0:606b230e5b4a 237 {
peterbarrett1967 0:606b230e5b4a 238 u8 b[6+1+16];
peterbarrett1967 0:606b230e5b4a 239 memset(b,0,sizeof(b));
peterbarrett1967 0:606b230e5b4a 240 memcpy(b,data,6);
peterbarrett1967 0:606b230e5b4a 241 b[6] = 4;
peterbarrett1967 0:606b230e5b4a 242 b[7] = '0';
peterbarrett1967 0:606b230e5b4a 243 b[8] = '0';
peterbarrett1967 0:606b230e5b4a 244 b[9] = '0';
peterbarrett1967 0:606b230e5b4a 245 b[10] = '0';
peterbarrett1967 0:606b230e5b4a 246 return SendCmd(HCI_OP_PIN_CODE_REPLY,b,sizeof(b));
peterbarrett1967 0:606b230e5b4a 247 }
peterbarrett1967 0:606b230e5b4a 248
peterbarrett1967 0:606b230e5b4a 249 void HCI::InquiryResult(const inquiry_info* info)
peterbarrett1967 0:606b230e5b4a 250 {
peterbarrett1967 0:606b230e5b4a 251 BTDevice* bt = Find(&info->bdaddr);
peterbarrett1967 0:606b230e5b4a 252 if (!bt) // new device
peterbarrett1967 0:606b230e5b4a 253 {
peterbarrett1967 0:606b230e5b4a 254 for (int i = 0; i < MAX_BTDEVICES; i++)
peterbarrett1967 0:606b230e5b4a 255 {
peterbarrett1967 0:606b230e5b4a 256 if (_devices[i]._state == 0)
peterbarrett1967 0:606b230e5b4a 257 {
peterbarrett1967 0:606b230e5b4a 258 bt = _devices + i;
peterbarrett1967 0:606b230e5b4a 259 bt->_state = 1;
peterbarrett1967 0:606b230e5b4a 260 break;
peterbarrett1967 0:606b230e5b4a 261 }
peterbarrett1967 0:606b230e5b4a 262 }
peterbarrett1967 0:606b230e5b4a 263 if (!bt)
peterbarrett1967 0:606b230e5b4a 264 {
peterbarrett1967 0:606b230e5b4a 265 printf("HCI::InquiryResult too many devices\n");
peterbarrett1967 0:606b230e5b4a 266 return; // Too many devices!
peterbarrett1967 0:606b230e5b4a 267 }
peterbarrett1967 0:606b230e5b4a 268 }
peterbarrett1967 0:606b230e5b4a 269
peterbarrett1967 0:606b230e5b4a 270 bt->_info = *info;
peterbarrett1967 0:606b230e5b4a 271 }
peterbarrett1967 0:606b230e5b4a 272
peterbarrett1967 0:606b230e5b4a 273 int HCI::GetDevices(BTDevice** devices, int maxDevices)
peterbarrett1967 0:606b230e5b4a 274 {
peterbarrett1967 0:606b230e5b4a 275 int j = 0;
peterbarrett1967 0:606b230e5b4a 276 for (int i = 0; i < MAX_BTDEVICES; i++)
peterbarrett1967 0:606b230e5b4a 277 {
peterbarrett1967 0:606b230e5b4a 278 if (_devices[i]._state != 0)
peterbarrett1967 0:606b230e5b4a 279 {
peterbarrett1967 0:606b230e5b4a 280 devices[j++] = _devices + i;
peterbarrett1967 0:606b230e5b4a 281 if (j == maxDevices)
peterbarrett1967 0:606b230e5b4a 282 break;
peterbarrett1967 0:606b230e5b4a 283 }
peterbarrett1967 0:606b230e5b4a 284 }
peterbarrett1967 0:606b230e5b4a 285 return j;
peterbarrett1967 0:606b230e5b4a 286 }
peterbarrett1967 0:606b230e5b4a 287
peterbarrett1967 0:606b230e5b4a 288 void HCI::RemoteName(const BD_ADDR* addr, const char* name)
peterbarrett1967 0:606b230e5b4a 289 {
peterbarrett1967 0:606b230e5b4a 290 BTDevice* d = Find(addr);
peterbarrett1967 0:606b230e5b4a 291 if (d)
peterbarrett1967 0:606b230e5b4a 292 {
peterbarrett1967 0:606b230e5b4a 293 strncpy(d->_name,name,sizeof(d->_name)-1);
peterbarrett1967 0:606b230e5b4a 294 d->_name[sizeof(d->_name)-1] = 0;
peterbarrett1967 0:606b230e5b4a 295 }
peterbarrett1967 0:606b230e5b4a 296 }
peterbarrett1967 0:606b230e5b4a 297
peterbarrett1967 0:606b230e5b4a 298 void HCI::ConnectComplete(const connection_info* info)
peterbarrett1967 0:606b230e5b4a 299 {
peterbarrett1967 0:606b230e5b4a 300 BTDevice* d = Find(&info->bdaddr);
peterbarrett1967 0:606b230e5b4a 301 if (!d)
peterbarrett1967 0:606b230e5b4a 302 return;
peterbarrett1967 0:606b230e5b4a 303 if (info->status == 0)
peterbarrett1967 0:606b230e5b4a 304 {
peterbarrett1967 0:606b230e5b4a 305 d->_handle = info->handle;
peterbarrett1967 0:606b230e5b4a 306 printf("Connected on %04X\n",info->handle);
peterbarrett1967 0:606b230e5b4a 307 } else
peterbarrett1967 0:606b230e5b4a 308 printf("Connection failed with %d\n",info->status);
peterbarrett1967 0:606b230e5b4a 309 }
peterbarrett1967 0:606b230e5b4a 310
peterbarrett1967 0:606b230e5b4a 311 void HCI::HCIRecv(const u8* data, int len)
peterbarrett1967 0:606b230e5b4a 312 {
peterbarrett1967 0:606b230e5b4a 313 // printfBytes(EvtStr(data[0]),data,min(len,16));
peterbarrett1967 0:606b230e5b4a 314 switch (data[0])
peterbarrett1967 0:606b230e5b4a 315 {
peterbarrett1967 0:606b230e5b4a 316 case HCI_EV_INQUIRY_COMPLETE:
peterbarrett1967 0:606b230e5b4a 317 printfBytes("Inquiry Complete",data,data[1]);
peterbarrett1967 0:606b230e5b4a 318 _state &= ~MASK_INQUIRY;
peterbarrett1967 0:606b230e5b4a 319 Callback(CALLBACK_INQUIRY_DONE,0,0);
peterbarrett1967 0:606b230e5b4a 320 break;
peterbarrett1967 0:606b230e5b4a 321
peterbarrett1967 0:606b230e5b4a 322 case HCI_EV_INQUIRY_RESULT:
peterbarrett1967 0:606b230e5b4a 323 {
peterbarrett1967 0:606b230e5b4a 324 const u8* end = data[1] + data + 2;
peterbarrett1967 0:606b230e5b4a 325 data += 3;
peterbarrett1967 0:606b230e5b4a 326 while (data < end)
peterbarrett1967 0:606b230e5b4a 327 {
peterbarrett1967 0:606b230e5b4a 328 inquiry_info align;
peterbarrett1967 0:606b230e5b4a 329 memcpy(&align,data,sizeof(inquiry_info));
peterbarrett1967 0:606b230e5b4a 330 InquiryResult(&align);
peterbarrett1967 0:606b230e5b4a 331 Callback(CALLBACK_INQUIRY_RESULT,(u8*)&align,sizeof(inquiry_info));
peterbarrett1967 0:606b230e5b4a 332 data += 14;
peterbarrett1967 0:606b230e5b4a 333 }
peterbarrett1967 0:606b230e5b4a 334 }
peterbarrett1967 0:606b230e5b4a 335 break;
peterbarrett1967 0:606b230e5b4a 336
peterbarrett1967 0:606b230e5b4a 337 case HCI_EV_CONN_COMPLETE:
peterbarrett1967 0:606b230e5b4a 338 _state &= ~MASK_CREATE_CONNECTION;
peterbarrett1967 0:606b230e5b4a 339 {
peterbarrett1967 0:606b230e5b4a 340 connection_info align;
peterbarrett1967 0:606b230e5b4a 341 memcpy(&align,data+2,sizeof(connection_info));
peterbarrett1967 0:606b230e5b4a 342 ConnectComplete(&align);
peterbarrett1967 0:606b230e5b4a 343 Callback(CALLBACK_CONNECTION_COMPLETE,(u8*)&align,sizeof(connection_info));
peterbarrett1967 0:606b230e5b4a 344 }
peterbarrett1967 0:606b230e5b4a 345 break;
peterbarrett1967 0:606b230e5b4a 346
peterbarrett1967 0:606b230e5b4a 347 case HCI_EV_CONN_REQUEST:
peterbarrett1967 0:606b230e5b4a 348 break;
peterbarrett1967 0:606b230e5b4a 349
peterbarrett1967 0:606b230e5b4a 350 case HCI_EV_DISCONN_COMPLETE:
peterbarrett1967 0:606b230e5b4a 351 DisconnectComplete(LE16(data+3));
peterbarrett1967 0:606b230e5b4a 352 break;
peterbarrett1967 0:606b230e5b4a 353
peterbarrett1967 0:606b230e5b4a 354 case HCI_EV_REMOTE_NAME:
peterbarrett1967 0:606b230e5b4a 355 {
peterbarrett1967 0:606b230e5b4a 356 BD_ADDR* addr = (BD_ADDR*)(data+3);
peterbarrett1967 0:606b230e5b4a 357 const char* name = (const char*)(data + 9);
peterbarrett1967 0:606b230e5b4a 358 RemoteName(addr,name);
peterbarrett1967 0:606b230e5b4a 359 }
peterbarrett1967 0:606b230e5b4a 360 Callback(CALLBACK_REMOTE_NAME,data+3,LE16(data+1)); // addr is in here too
peterbarrett1967 0:606b230e5b4a 361 _state &= ~MASK_REMOTE_NAME;
peterbarrett1967 0:606b230e5b4a 362 break;
peterbarrett1967 0:606b230e5b4a 363
peterbarrett1967 0:606b230e5b4a 364 case HCI_EV_CMD_STATUS:
peterbarrett1967 0:606b230e5b4a 365 {
peterbarrett1967 0:606b230e5b4a 366 const char* errs = HCIErrStr(data[2]);
peterbarrett1967 0:606b230e5b4a 367 printf("Status %s %s\n",CmdStr(LE16(data+4)),errs);
peterbarrett1967 0:606b230e5b4a 368 }
peterbarrett1967 0:606b230e5b4a 369 break;
peterbarrett1967 0:606b230e5b4a 370
peterbarrett1967 0:606b230e5b4a 371 case HCI_EV_CMD_COMPLETE:
peterbarrett1967 0:606b230e5b4a 372 OnCommandComplete(data[3] | (data[4] << 8),data+6,data[1]-4);
peterbarrett1967 0:606b230e5b4a 373 break;
peterbarrett1967 0:606b230e5b4a 374
peterbarrett1967 0:606b230e5b4a 375 case HCI_EV_PIN_CODE_REQ:
peterbarrett1967 0:606b230e5b4a 376 PinCodeReply(data+2);
peterbarrett1967 0:606b230e5b4a 377 break;
peterbarrett1967 0:606b230e5b4a 378
peterbarrett1967 0:606b230e5b4a 379 case HCI_EV_LINK_KEY_REQ:
peterbarrett1967 0:606b230e5b4a 380 SendCmd(HCI_OP_LINK_KEY_NEG_REPLY,data+2,6);
peterbarrett1967 0:606b230e5b4a 381 break;
peterbarrett1967 0:606b230e5b4a 382
peterbarrett1967 0:606b230e5b4a 383 default:
peterbarrett1967 0:606b230e5b4a 384 ;
peterbarrett1967 0:606b230e5b4a 385 // printfBytes(":",data,data[1]+2);
peterbarrett1967 0:606b230e5b4a 386 }
peterbarrett1967 0:606b230e5b4a 387 }
peterbarrett1967 0:606b230e5b4a 388
peterbarrett1967 0:606b230e5b4a 389 int HCI::Open(SocketInternal* sock, SocketAddrHdr* addr)
peterbarrett1967 0:606b230e5b4a 390 {
peterbarrett1967 0:606b230e5b4a 391 L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
peterbarrett1967 0:606b230e5b4a 392 L2CAPAddr* l2capaddr = (L2CAPAddr*)addr;
peterbarrett1967 0:606b230e5b4a 393 BTDevice* bt = Find(&l2capaddr->bdaddr);
peterbarrett1967 0:606b230e5b4a 394 if (!bt)
peterbarrett1967 0:606b230e5b4a 395 {
peterbarrett1967 0:606b230e5b4a 396 printf("Can't open l2cap %d on ",l2capaddr->psm);
peterbarrett1967 0:606b230e5b4a 397 printf(&l2capaddr->bdaddr);
peterbarrett1967 0:606b230e5b4a 398 printf("\n");
peterbarrett1967 0:606b230e5b4a 399 return ERR_HCI_DEVICE_NOT_FOUND;
peterbarrett1967 0:606b230e5b4a 400 }
peterbarrett1967 0:606b230e5b4a 401 l2capsock->btdevice = bt;
peterbarrett1967 0:606b230e5b4a 402 return bt->Open(sock,addr);
peterbarrett1967 0:606b230e5b4a 403 }
peterbarrett1967 0:606b230e5b4a 404
peterbarrett1967 0:606b230e5b4a 405 int HCI::Send(SocketInternal* sock, const u8* data, int len)
peterbarrett1967 0:606b230e5b4a 406 {
peterbarrett1967 0:606b230e5b4a 407 L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
peterbarrett1967 0:606b230e5b4a 408 return l2capsock->btdevice->Send(sock,data,len); // Pointless double dispatch
peterbarrett1967 0:606b230e5b4a 409 }
peterbarrett1967 0:606b230e5b4a 410
peterbarrett1967 0:606b230e5b4a 411 int HCI::Close(SocketInternal* sock)
peterbarrett1967 0:606b230e5b4a 412 {
peterbarrett1967 0:606b230e5b4a 413 L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
peterbarrett1967 0:606b230e5b4a 414 return l2capsock->btdevice->Close(sock); // Pointless double dispatch
peterbarrett1967 0:606b230e5b4a 415 }
peterbarrett1967 0:606b230e5b4a 416
peterbarrett1967 0:606b230e5b4a 417 void HCI::ACLRecv(const u8* data, int len)
peterbarrett1967 0:606b230e5b4a 418 {
peterbarrett1967 0:606b230e5b4a 419 int handle = LE16(data);
peterbarrett1967 0:606b230e5b4a 420 BTDevice* d = Find(handle & 0x0FFF);
peterbarrett1967 0:606b230e5b4a 421 if (d)
peterbarrett1967 0:606b230e5b4a 422 d->ACLRecv(data,len);
peterbarrett1967 0:606b230e5b4a 423 }
peterbarrett1967 0:606b230e5b4a 424
peterbarrett1967 0:606b230e5b4a 425 //===================================================================
peterbarrett1967 0:606b230e5b4a 426 //===================================================================