BlackOneとAndroidの連携デモプログラム AndroidAccessoryを改造してBlackOneとAndroidが連携できるようにしました。 サポートしているのは、デモアプリの ”Buttons” B1-SW1, B2-SW2, B3-SW3 ”LED2” RGB-LED のみです。 LCDに表示するイメージをマイクロSDカードに入れてLCDのソケットに挿入しておく必要があります。 イメージは、320X240ドットで”\Image”という名前のフォルダの直下に”10.jpg”という名前で入れてください。

Dependencies:   TextLCD mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hci.cpp Source File

hci.cpp

00001 /*
00002 Copyright (c) 2010 Peter Barrett
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020 THE SOFTWARE.
00021 */
00022 
00023 /* 
00024 Tue Apr 26 2011 Bart Janssens: added HCI connection accept
00025 */
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 
00032 #include "Utils.h"
00033 #include "hci.h"
00034 #include "hci_private.h"
00035 
00036 enum hci_callback_evt
00037 {
00038     NONE,
00039     CONNECT,
00040     DISCONECT,
00041     INQUIRYRESULT
00042 };
00043 
00044 #define MAX_BLUETOOTH_ADAPTERS 1
00045 
00046 enum StateMask {
00047     MASK_RESET = 1,
00048     MASK_READ_BUFFER_SIZE = 2,
00049     MASK_READ_BD_ADDR = 4,
00050     MASK_INITED = 8,
00051     MASK_INQUIRY = 16,
00052     MASK_REMOTE_NAME = 32,
00053     MASK_CREATE_CONNECTION = 64
00054 };
00055 
00056 int  HCI::Open(HCITransport* transport, HCICallback callback)
00057 {
00058     _transport = transport;
00059     _transport->Set(this);
00060     _callback = callback;
00061     _state = 0;
00062     for (int i = 0; i < MAX_BTDEVICES; i++)
00063     {
00064         _devices[i].Init();
00065         _devices[i]._transport = transport;
00066     }
00067     return SendCmd(HCI_OP_RESET);
00068 }
00069 
00070 void printf(const BD_ADDR* addr);
00071 
00072 BTDevice* HCI::Find(const BD_ADDR* addr)
00073 {
00074     for (int i = 0; i < MAX_BTDEVICES; i++)
00075         if (_devices[i]._state != 0 && memcmp(addr,&_devices[i]._info.bdaddr,6) == 0)
00076             return &_devices[i];
00077     return 0;
00078 }
00079 
00080 BTDevice* HCI::Find(int handle)
00081 {
00082     for (int i = 0; i < MAX_BTDEVICES; i++)
00083         if (_devices[i]._state != 0 && handle == _devices[i]._handle)
00084             return &_devices[i];
00085     return 0;
00086 }
00087 //
00088 bool HCI::Busy()
00089 {
00090     return (_state & (MASK_INQUIRY | MASK_REMOTE_NAME | MASK_CREATE_CONNECTION)) != 0;
00091 }
00092 
00093 int HCI::Inquiry(int duration)
00094 {
00095     _state |= MASK_INQUIRY;
00096     u8 buf[5];
00097     buf[0] = 0x33;
00098     buf[1] = 0x8B;
00099     buf[2] = 0x9E;
00100     buf[3] = duration;
00101     buf[4] = 5;  // 5 results
00102     SendCmd(HCI_OP_INQUIRY,buf,sizeof(buf));
00103     return 0;
00104 }
00105 
00106 int HCI::WriteScanEnable()
00107 {
00108    
00109     u8 buf[2];
00110     buf[0] = 0x03;
00111     buf[1] = 0x01;    
00112     
00113     SendCmd(HCI_OP_WRITE_SCAN_ENABLE,buf,sizeof(buf));
00114     return 0;
00115 }
00116 
00117 int HCI::AcceptConnection(const BD_ADDR* addr)
00118 {
00119     u8 buf[6+4];
00120     memset(buf,0,sizeof(buf));
00121     memcpy(buf,addr,6);
00122     buf[7] = 0;      
00123     
00124     SendCmd(HCI_OP_ACCEPT_CONN_REQ,buf,sizeof(buf));
00125     return 0;
00126 }
00127 
00128 int HCI::SendCmd(int cmd, const u8* params, int len)
00129 {
00130     u8 b[32];
00131     b[0] = cmd;
00132     b[1] = (cmd >> 8);
00133     b[2] = len;
00134     if (params)
00135         memcpy(b+3,params,len);
00136     _transport->HCISend(b,len+3);
00137     return 0;
00138 }
00139 
00140 void HCI::OnCommandComplete(int cmd, const u8* data, int len)
00141 {
00142    // printf("%04X %s",cmd,CmdStr(cmd));
00143     if (len < 0)
00144         return;
00145     //printfBytes(" complete",data,min(16,len));
00146 
00147     switch (cmd)
00148     {
00149         //  Init phase 0
00150         case HCI_OP_RESET:  // Reset done, init chain to HCI_OP_READ_LOCAL_NAME
00151             SendCmd(HCI_OP_READ_BUFFER_SIZE);
00152             _state |= MASK_RESET;
00153             break;
00154 
00155         //  Init phase 1
00156         case HCI_OP_READ_BUFFER_SIZE:
00157             _acl_mtu = LE16(data);
00158             _sco_mtu = data[2];
00159             _acl_max_pkt = LE16(data+3);
00160             _sco_max_pkt = LE16(data+5);
00161             SendCmd(HCI_OP_READ_BD_ADDR);
00162             _state |= MASK_READ_BUFFER_SIZE;
00163             break;
00164 
00165         //  Init phase 2
00166         case HCI_OP_READ_BD_ADDR:
00167             _localAddr = *((BD_ADDR*)data); // Local Address
00168             printf("Local Address: ");
00169              printf(&_localAddr);
00170              printf("\r\n");
00171              
00172             _state |= MASK_READ_BD_ADDR;
00173             _state |= MASK_INITED;
00174             Callback(CALLBACK_READY,data,6);
00175             break;
00176 
00177                    // 0CXX
00178         case HCI_OP_READ_LOCAL_NAME:
00179             break;
00180 
00181         case HCI_OP_READ_LOCAL_VERSION:
00182             // params
00183             //SendCmd(HCI_OP_READ_LOCAL_NAME);
00184             break;
00185 
00186         case HCI_OP_READ_LOCAL_COMMANDS:
00187             break;
00188 
00189         case HCI_OP_READ_LOCAL_FEATURES:
00190             //SendCmd(HCI_OP_READ_LOCAL_VERSION);
00191             break;
00192 
00193         case HCI_OP_READ_LOCAL_EXT_FEATURES:
00194             break;
00195 
00196         case HCI_OP_PIN_CODE_REPLY:
00197             printf("Got pin reply\r\n");
00198             break;
00199 
00200         default:
00201             //printf("Unrecognized Command %04X\r\n",cmd);
00202             break;
00203     }
00204 }
00205 
00206 void HCI::Callback(HCI_CALLBACK_EVENT c, const u8* data, int len)
00207 {
00208     _callback(this,c,data,len);
00209 }
00210 
00211 int HCI::RemoteNameRequest(const BD_ADDR* addr)
00212 {
00213     _state |= MASK_REMOTE_NAME;
00214     u8 buf[6+4];
00215     memset(buf,0,sizeof(buf));
00216     memcpy(buf,addr,6);
00217     buf[7] = 1;
00218     return SendCmd(HCI_OP_REMOTE_NAME_REQ,buf,sizeof(buf));
00219 }
00220 
00221 int HCI::CreateConnection(const BD_ADDR* remoteAddr)
00222 {
00223     _state |= MASK_CREATE_CONNECTION;
00224     u8 buf[6+7];
00225     memset(buf,0,sizeof(buf));
00226     memcpy(buf,remoteAddr,6);
00227     buf[6] = 0x18;  // DM1,DH1
00228     buf[7] = 0xCC;  // DM3, DH3, DM5, DH5
00229     buf[8] = 1;     // Page Repetition R1
00230     return SendCmd(HCI_OP_CREATE_CONN,buf,sizeof(buf));
00231 }
00232 
00233 int HCI::Disconnect(const BD_ADDR* bdaddr)
00234 {
00235     BTDevice* d = Find(bdaddr);
00236     if (!d)
00237         return ERR_HCI_DEVICE_NOT_FOUND;
00238     int handle = d->_handle;
00239     printf("Disconnect from %d\r\n",handle);
00240     _state |= MASK_CREATE_CONNECTION;
00241     u8 buf[3];
00242     buf[0] = handle;
00243     buf[1] = (handle >> 8);
00244     buf[2] = 0x13;
00245     return SendCmd(HCI_OP_DISCONNECT,buf,sizeof(buf));
00246 }
00247 
00248 void HCI::DisconnectComplete(int handle)
00249 {
00250     BTDevice* d = Find(handle);
00251     if (!d)
00252         return;
00253     d->_handle = 0;
00254 }
00255 
00256 int HCI::DisconnectAll()
00257 {
00258     BTDevice* devs[8];
00259     int count = GetDevices(devs,8);
00260     for (int i = 0; i < count; i++)
00261         Disconnect(&devs[i]->_info.bdaddr);
00262     return 0;
00263 }
00264 
00265 int HCI::PinCodeReply(const u8* data)
00266 {
00267     u8 b[6+1+16];
00268     memset(b,0,sizeof(b));
00269     memcpy(b,data,6);
00270     b[6] = 4;
00271     b[7] = '0';
00272     b[8] = '0';
00273     b[9] = '0';
00274     b[10] = '0';
00275     return SendCmd(HCI_OP_PIN_CODE_REPLY,b,sizeof(b));
00276 }
00277 
00278 void HCI::InquiryResult(const inquiry_info* info)
00279 {
00280     BTDevice* bt = Find(&info->bdaddr);
00281     if (!bt)    // new device
00282     {
00283         for (int i = 0; i < MAX_BTDEVICES; i++)
00284         {
00285             if (_devices[i]._state == 0)
00286             {
00287                 bt = _devices + i;
00288                 bt->_state = 1;
00289                 break;
00290             }
00291         }
00292         if (!bt)
00293         {
00294             printf("HCI::InquiryResult too many devices\r\n");
00295             return; // Too many devices!
00296         }
00297     }
00298 
00299     bt->_info = *info;
00300 }
00301 
00302 int HCI::GetDevices(BTDevice** devices, int maxDevices)
00303 {
00304     int j = 0;
00305     for (int i = 0; i < MAX_BTDEVICES; i++)
00306     {
00307         if (_devices[i]._state != 0)
00308         {
00309             devices[j++] = _devices + i;
00310             if (j == maxDevices)
00311                 break;
00312         }
00313     }
00314     return j;
00315 }
00316 
00317 void HCI::RemoteName(const BD_ADDR* addr, const char* name)
00318 {
00319     BTDevice* d = Find(addr);
00320     if (d)
00321     {
00322         strncpy(d->_name,name,sizeof(d->_name)-1);
00323         d->_name[sizeof(d->_name)-1] = 0;
00324     }
00325 }
00326 
00327 void HCI::ConnectComplete(const connection_info* info)
00328 {
00329     BTDevice* d = Find(&info->bdaddr);
00330     if (!d)
00331         return;
00332     if (info->status == 0)
00333     {
00334         d->_handle = info->handle;
00335         printf("Connected on %04X\r\n",info->handle);
00336     } else
00337         printf("Connection failed with %d\r\n",info->status);
00338 }
00339 
00340 void HCI::ConnectRequest(const request_info* info)
00341 {
00342     BTDevice* bt = Find(&info->bdaddr);
00343     if (!bt)    // new device
00344     {
00345         for (int i = 0; i < MAX_BTDEVICES; i++)
00346         {
00347             if (_devices[i]._state == 0)
00348             {
00349                 bt = _devices + i;
00350                 bt->_state = 1;
00351                 break;
00352             }
00353         }
00354         if (!bt)
00355         {
00356             printf("HCI::ConnectRequest too many devices\r\n");
00357             return; // Too many devices!
00358         }
00359     }
00360    bt->_info.bdaddr = info->bdaddr;
00361    memcpy(bt->_info.dev_class,info->dev_class,3);
00362    AcceptConnection(&info->bdaddr);
00363 }
00364 
00365 void HCI::HCIRecv(const u8* data, int len)
00366 {
00367     //printfBytes(EvtStr(data[0]),data,len);
00368     //printfBytes(EvtStr(data[0]),data,min(len,16));
00369     //printf("HCI Event %02X\r\n",data[0]);
00370     switch (data[0])
00371     {
00372         case HCI_EV_INQUIRY_COMPLETE:
00373             printfBytes("Inquiry Complete",data,data[1]);
00374             _state &= ~MASK_INQUIRY;
00375             Callback(CALLBACK_INQUIRY_DONE,0,0);
00376             WriteScanEnable();
00377             break;
00378 
00379         case HCI_EV_INQUIRY_RESULT:
00380             {
00381                 const u8* end = data[1] + data + 2;
00382                 data += 3;
00383                 while (data < end)
00384                 {
00385                     inquiry_info align;
00386                     memcpy(&align,data,sizeof(inquiry_info));
00387                     InquiryResult(&align);
00388                     Callback(CALLBACK_INQUIRY_RESULT,(u8*)&align,sizeof(inquiry_info));
00389                     data += 14;
00390                 }
00391             }
00392             break;
00393 
00394         case HCI_EV_CONN_COMPLETE:
00395             _state &= ~MASK_CREATE_CONNECTION;
00396             {
00397                 connection_info align;
00398                 memcpy(&align,data+2,sizeof(connection_info));
00399                 ConnectComplete(&align);
00400                 Callback(CALLBACK_CONNECTION_COMPLETE,(u8*)&align,sizeof(connection_info));
00401             }
00402             break;
00403 
00404         case HCI_EV_CONN_REQUEST:
00405             {
00406                 request_info align;
00407                 memcpy(&align,data+2,sizeof(request_info));
00408                 ConnectRequest(&align);
00409             }
00410             break;
00411 
00412         case HCI_EV_DISCONN_COMPLETE:
00413             DisconnectComplete(LE16(data+3));
00414             break;
00415 
00416         case HCI_EV_REMOTE_NAME:
00417             {
00418                 BD_ADDR* addr = (BD_ADDR*)(data+3);
00419                 const char* name = (const char*)(data + 9);
00420                 RemoteName(addr,name);
00421             }
00422             Callback(CALLBACK_REMOTE_NAME,data+3,LE16(data+1));    // addr is in here too
00423             _state &= ~MASK_REMOTE_NAME;
00424             break;
00425 
00426         case HCI_EV_CMD_STATUS:
00427             {
00428                 const char* errs = HCIErrStr(data[2]);
00429                 printf("Status %s %s\r\n",CmdStr(LE16(data+4)),errs);
00430             }
00431             break;
00432 
00433         case HCI_EV_CMD_COMPLETE:
00434             OnCommandComplete(data[3] | (data[4] << 8),data+6,data[1]-4);
00435             break;
00436 
00437         case HCI_EV_PIN_CODE_REQ:
00438             PinCodeReply(data+2);
00439             break;
00440 
00441         case HCI_EV_LINK_KEY_REQ:
00442             SendCmd(HCI_OP_LINK_KEY_NEG_REPLY,data+2,6);
00443             break;
00444 
00445         default:
00446         ;
00447            // printfBytes("HCI Event:",data,data[1]+2);
00448     }
00449 }
00450 
00451 int HCI::Open(SocketInternal* sock, SocketAddrHdr* addr)
00452 {
00453     L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
00454     L2CAPAddr* l2capaddr = (L2CAPAddr*)addr;
00455     BTDevice* bt = Find(&l2capaddr->bdaddr);
00456     if (!bt)
00457     {
00458         printf("Can't open l2cap %d on ",l2capaddr->psm);
00459         printf(&l2capaddr->bdaddr);
00460         printf("\r\n");
00461         return ERR_HCI_DEVICE_NOT_FOUND;
00462     }
00463     l2capsock->btdevice = bt;
00464     return bt->Open(sock,addr);
00465 }
00466 
00467 int HCI::Create(SocketInternal* sock, SocketAddrHdr* addr)
00468 {
00469     L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
00470     L2CAPAddr* l2capaddr = (L2CAPAddr*)addr;
00471     BTDevice* bt = Find(&l2capaddr->bdaddr);
00472     if (!bt)
00473     {
00474         printf("HCI Create: Can't open l2cap on ");
00475         printf(&l2capaddr->bdaddr);
00476         printf("\r\n");
00477         return ERR_HCI_DEVICE_NOT_FOUND;
00478     }
00479     l2capsock->btdevice = bt;
00480     //return 0;
00481     return bt->Create(sock,addr);
00482 }
00483 
00484 
00485 int HCI::Accept(SocketInternal* sock, SocketAddrHdr* addr)
00486 {
00487 
00488     printf("Call to HCI Accept \r\n"); 
00489     
00490     L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
00491     L2CAPAddr* l2capaddr = (L2CAPAddr*)addr;
00492     BTDevice* bt = Find(&l2capaddr->bdaddr);
00493     if (!bt)
00494     {
00495         //printf("Can't open l2cap %d on ",l2capaddr->psm);
00496         printf("HCI Accept: Can't open l2cap on ");
00497         printf(&l2capaddr->bdaddr);
00498         printf("\r\n");
00499         return ERR_HCI_DEVICE_NOT_FOUND;
00500     }
00501     //l2capsock->btdevice = bt;
00502     return bt->Open(sock,addr);
00503         
00504 }
00505 
00506 /**
00507 SocketInternal* HCI::Create(SocketInternal* sock)
00508 {
00509     return sock;    
00510 }
00511 **/
00512 
00513 
00514 int HCI::Send(SocketInternal* sock, const u8* data, int len)
00515 {
00516     L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
00517     return l2capsock->btdevice->Send(sock,data,len);    // Pointless double dispatch
00518 }
00519 
00520 int HCI::Close(SocketInternal* sock)
00521 {
00522     L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
00523     return l2capsock->btdevice->Close(sock);    // Pointless double dispatch
00524 }
00525 
00526 void HCI::ACLRecv(const u8* data, int len)
00527 {
00528     int handle = LE16(data);
00529     BD_ADDR* addr;
00530     BTDevice* d = Find(handle & 0x0FFF);
00531     addr = &d->_info.bdaddr;
00532     
00533     if (d)
00534         d->ACLRecv(addr,data,len);
00535 }
00536 
00537 //===================================================================
00538 //===================================================================