type mini keyboard and display LCD

Dependencies:   mbed

Committer:
joenagata
Date:
Sat Feb 26 07:24:32 2011 +0000
Revision:
0:e5197e77ab57
rev.1

Who changed what in which revision?

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