Joe Nagata / BlueUSB

Description: type mini keyboard and display LCD

Committer:
user Joe Nagata
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
user Joe Nagata0:e5197e77ab57 1/*
user Joe Nagata0:e5197e77ab57 2Copyright (c) 2010 Peter Barrett
user Joe Nagata0:e5197e77ab57 3
user Joe Nagata0:e5197e77ab57 4Permission is hereby granted, free of charge, to any person obtaining a copy
user Joe Nagata0:e5197e77ab57 5of this software and associated documentation files (the "Software"), to deal
user Joe Nagata0:e5197e77ab57 6in the Software without restriction, including without limitation the rights
user Joe Nagata0:e5197e77ab57 7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
user Joe Nagata0:e5197e77ab57 8copies of the Software, and to permit persons to whom the Software is
user Joe Nagata0:e5197e77ab57 9furnished to do so, subject to the following conditions:
user Joe Nagata0:e5197e77ab57 10
user Joe Nagata0:e5197e77ab57 11The above copyright notice and this permission notice shall be included in
user Joe Nagata0:e5197e77ab57 12all copies or substantial portions of the Software.
user Joe Nagata0:e5197e77ab57 13
user Joe Nagata0:e5197e77ab57 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
user Joe Nagata0:e5197e77ab57 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
user Joe Nagata0:e5197e77ab57 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
user Joe Nagata0:e5197e77ab57 17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
user Joe Nagata0:e5197e77ab57 18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
user Joe Nagata0:e5197e77ab57 19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
user Joe Nagata0:e5197e77ab57 20THE SOFTWARE.
user Joe Nagata0:e5197e77ab57 21*/
user Joe Nagata0:e5197e77ab57 22
user Joe Nagata0:e5197e77ab57 23
user Joe Nagata0:e5197e77ab57 24#include <stdio.h>
user Joe Nagata0:e5197e77ab57 25#include <stdlib.h>
user Joe Nagata0:e5197e77ab57 26#include <stdio.h>
user Joe Nagata0:e5197e77ab57 27#include <string.h>
user Joe Nagata0:e5197e77ab57 28
user Joe Nagata0:e5197e77ab57 29#include "Utils.h"
user Joe Nagata0:e5197e77ab57 30#include "hci.h"
user Joe Nagata0:e5197e77ab57 31
user Joe Nagata0:e5197e77ab57 32#define L2CAP_COMMAND_REJ 0x01
user Joe Nagata0:e5197e77ab57 33#define L2CAP_CONN_REQ 0x02
user Joe Nagata0:e5197e77ab57 34#define L2CAP_CONN_RSP 0x03
user Joe Nagata0:e5197e77ab57 35#define L2CAP_CONF_REQ 0x04
user Joe Nagata0:e5197e77ab57 36#define L2CAP_CONF_RSP 0x05
user Joe Nagata0:e5197e77ab57 37#define L2CAP_DISCONN_REQ 0x06
user Joe Nagata0:e5197e77ab57 38#define L2CAP_DISCONN_RSP 0x07
user Joe Nagata0:e5197e77ab57 39#define L2CAP_ECHO_REQ 0x08
user Joe Nagata0:e5197e77ab57 40#define L2CAP_ECHO_RSP 0x09
user Joe Nagata0:e5197e77ab57 41#define L2CAP_INFO_REQ 0x0a
user Joe Nagata0:e5197e77ab57 42#define L2CAP_INFO_RSP 0x0b
user Joe Nagata0:e5197e77ab57 43
user Joe Nagata0:e5197e77ab57 44
user Joe Nagata0:e5197e77ab57 45 /* L2CAP command codes */
user Joe Nagata0:e5197e77ab57 46 const char* L2CAP_ComandCodeStr(int c)
user Joe Nagata0:e5197e77ab57 47 {
user Joe Nagata0:e5197e77ab57 48 switch (c)
user Joe Nagata0:e5197e77ab57 49 {
user Joe Nagata0:e5197e77ab57 50 case L2CAP_COMMAND_REJ: return "L2CAP_COMMAND_REJ";
user Joe Nagata0:e5197e77ab57 51 case L2CAP_CONN_REQ: return "L2CAP_CONN_REQ";
user Joe Nagata0:e5197e77ab57 52 case L2CAP_CONN_RSP: return "L2CAP_CONN_RSP";
user Joe Nagata0:e5197e77ab57 53 case L2CAP_CONF_REQ: return "L2CAP_CONF_REQ";
user Joe Nagata0:e5197e77ab57 54 case L2CAP_CONF_RSP: return "L2CAP_CONF_RSP";
user Joe Nagata0:e5197e77ab57 55 case L2CAP_DISCONN_REQ: return "L2CAP_DISCONN_REQ";
user Joe Nagata0:e5197e77ab57 56 case L2CAP_DISCONN_RSP: return "L2CAP_DISCONN_RSP";
user Joe Nagata0:e5197e77ab57 57 case L2CAP_ECHO_REQ: return "L2CAP_ECHO_REQ";
user Joe Nagata0:e5197e77ab57 58 case L2CAP_ECHO_RSP: return "L2CAP_ECHO_RSP";
user Joe Nagata0:e5197e77ab57 59 case L2CAP_INFO_REQ: return "L2CAP_INFO_REQ";
user Joe Nagata0:e5197e77ab57 60 case L2CAP_INFO_RSP: return "L2CAP_INFO_RSP";
user Joe Nagata0:e5197e77ab57 61 }
user Joe Nagata0:e5197e77ab57 62 return "unknown";
user Joe Nagata0:e5197e77ab57 63 }
user Joe Nagata0:e5197e77ab57 64
user Joe Nagata0:e5197e77ab57 65typedef struct
user Joe Nagata0:e5197e77ab57 66{
user Joe Nagata0:e5197e77ab57 67 u16 handle;
user Joe Nagata0:e5197e77ab57 68 u16 length; // total
user Joe Nagata0:e5197e77ab57 69 u16 l2capLength; // length -4
user Joe Nagata0:e5197e77ab57 70 u16 cid; // Signaling packet CID = 1
user Joe Nagata0:e5197e77ab57 71 u8 data[64]; // Largest thing to send!!! todo
user Joe Nagata0:e5197e77ab57 72} L2CAPData;
user Joe Nagata0:e5197e77ab57 73
user Joe Nagata0:e5197e77ab57 74typedef struct
user Joe Nagata0:e5197e77ab57 75{
user Joe Nagata0:e5197e77ab57 76 u16 handle;
user Joe Nagata0:e5197e77ab57 77 u16 length; // total
user Joe Nagata0:e5197e77ab57 78 u16 l2capLength; // length -4
user Joe Nagata0:e5197e77ab57 79 u16 cid; // Signaling packet CID = 1
user Joe Nagata0:e5197e77ab57 80
user Joe Nagata0:e5197e77ab57 81 // Payload
user Joe Nagata0:e5197e77ab57 82 u8 cmd; //
user Joe Nagata0:e5197e77ab57 83 u8 id;
user Joe Nagata0:e5197e77ab57 84 u16 cmdLength; // total-8
user Joe Nagata0:e5197e77ab57 85 u16 params[4]; // Params
user Joe Nagata0:e5197e77ab57 86} L2CAPCmd;
user Joe Nagata0:e5197e77ab57 87
user Joe Nagata0:e5197e77ab57 88//
user Joe Nagata0:e5197e77ab57 89void BTDevice::Init()
user Joe Nagata0:e5197e77ab57 90{
user Joe Nagata0:e5197e77ab57 91 memset(&_info,0,sizeof(inquiry_info));
user Joe Nagata0:e5197e77ab57 92 _handle = 0;
user Joe Nagata0:e5197e77ab57 93 _name[0] = 0;
user Joe Nagata0:e5197e77ab57 94 _state = 0;
user Joe Nagata0:e5197e77ab57 95}
user Joe Nagata0:e5197e77ab57 96
user Joe Nagata0:e5197e77ab57 97// virtual SocketHandler
user Joe Nagata0:e5197e77ab57 98int BTDevice::Open(SocketInternal* sock, SocketAddrHdr* addr)
user Joe Nagata0:e5197e77ab57 99{
user Joe Nagata0:e5197e77ab57 100 L2CAPSocket* s = (L2CAPSocket*)sock;
user Joe Nagata0:e5197e77ab57 101 L2CAPAddr* a = (L2CAPAddr*)addr;
user Joe Nagata0:e5197e77ab57 102 s->scid = 0x40 + sock->ID-1; // are these reserved?
user Joe Nagata0:e5197e77ab57 103 s->dcid = 0;
user Joe Nagata0:e5197e77ab57 104 Connect(s->scid,a->psm);
user Joe Nagata0:e5197e77ab57 105 return sock->ID;
user Joe Nagata0:e5197e77ab57 106}
user Joe Nagata0:e5197e77ab57 107
user Joe Nagata0:e5197e77ab57 108// virtual SocketHandler
user Joe Nagata0:e5197e77ab57 109int BTDevice::Send(SocketInternal* sock, const u8* data, int len)
user Joe Nagata0:e5197e77ab57 110{
user Joe Nagata0:e5197e77ab57 111 L2CAPData d;
user Joe Nagata0:e5197e77ab57 112 L2CAPSocket* s = (L2CAPSocket*)sock;
user Joe Nagata0:e5197e77ab57 113
user Joe Nagata0:e5197e77ab57 114 d.handle = _handle | 0x2000;
user Joe Nagata0:e5197e77ab57 115 d.length = 4 + len;
user Joe Nagata0:e5197e77ab57 116 d.l2capLength = len;
user Joe Nagata0:e5197e77ab57 117 d.cid = s->dcid;
user Joe Nagata0:e5197e77ab57 118
user Joe Nagata0:e5197e77ab57 119 if (len > 64)
user Joe Nagata0:e5197e77ab57 120 return -1;
user Joe Nagata0:e5197e77ab57 121 memcpy(d.data,data,len);
user Joe Nagata0:e5197e77ab57 122 return Send((u8*)&d,len+8);
user Joe Nagata0:e5197e77ab57 123}
user Joe Nagata0:e5197e77ab57 124
user Joe Nagata0:e5197e77ab57 125// virtual SocketHandler
user Joe Nagata0:e5197e77ab57 126int BTDevice::Close(SocketInternal* sock)
user Joe Nagata0:e5197e77ab57 127{
user Joe Nagata0:e5197e77ab57 128 printf("L2CAP close %d\n",sock->ID);
user Joe Nagata0:e5197e77ab57 129 L2CAPSocket* s = (L2CAPSocket*)sock;
user Joe Nagata0:e5197e77ab57 130 return Disconnect(s->scid,s->dcid);
user Joe Nagata0:e5197e77ab57 131}
user Joe Nagata0:e5197e77ab57 132
user Joe Nagata0:e5197e77ab57 133L2CAPSocket* BTDevice::SCIDToSocket(int scid)
user Joe Nagata0:e5197e77ab57 134{
user Joe Nagata0:e5197e77ab57 135 return (L2CAPSocket*)GetSocketInternal(scid-0x40+1);
user Joe Nagata0:e5197e77ab57 136}
user Joe Nagata0:e5197e77ab57 137
user Joe Nagata0:e5197e77ab57 138int BTDevice::Send(const u8* data, int len)
user Joe Nagata0:e5197e77ab57 139{
user Joe Nagata0:e5197e77ab57 140 _transport->ACLSend(data,len);
user Joe Nagata0:e5197e77ab57 141 return 0;
user Joe Nagata0:e5197e77ab57 142}
user Joe Nagata0:e5197e77ab57 143
user Joe Nagata0:e5197e77ab57 144int BTDevice::Send(u8 c, u8 id, u16* params, int count)
user Joe Nagata0:e5197e77ab57 145{
user Joe Nagata0:e5197e77ab57 146 L2CAPCmd cmd;
user Joe Nagata0:e5197e77ab57 147 cmd.handle = _handle | 0x2000;
user Joe Nagata0:e5197e77ab57 148 cmd.length = 8 + count*2;
user Joe Nagata0:e5197e77ab57 149
user Joe Nagata0:e5197e77ab57 150 cmd.l2capLength = cmd.length-4;
user Joe Nagata0:e5197e77ab57 151 cmd.cid = 1; // Signaling packet
user Joe Nagata0:e5197e77ab57 152
user Joe Nagata0:e5197e77ab57 153 cmd.cmd = c;
user Joe Nagata0:e5197e77ab57 154 cmd.id = id;
user Joe Nagata0:e5197e77ab57 155 cmd.cmdLength = count*2;
user Joe Nagata0:e5197e77ab57 156 for (int i = 0; i < count; i++)
user Joe Nagata0:e5197e77ab57 157 cmd.params[i] = params[i];
user Joe Nagata0:e5197e77ab57 158 return Send((u8*)&cmd,cmd.length+4);
user Joe Nagata0:e5197e77ab57 159}
user Joe Nagata0:e5197e77ab57 160
user Joe Nagata0:e5197e77ab57 161int BTDevice::Connect(int scid, int psm)
user Joe Nagata0:e5197e77ab57 162{
user Joe Nagata0:e5197e77ab57 163 u16 p[2];
user Joe Nagata0:e5197e77ab57 164 p[0] = psm;
user Joe Nagata0:e5197e77ab57 165 p[1] = scid;
user Joe Nagata0:e5197e77ab57 166 return Send(L2CAP_CONN_REQ,_txid++,p,2);
user Joe Nagata0:e5197e77ab57 167}
user Joe Nagata0:e5197e77ab57 168
user Joe Nagata0:e5197e77ab57 169int BTDevice::Disconnect(int scid, int dcid)
user Joe Nagata0:e5197e77ab57 170{
user Joe Nagata0:e5197e77ab57 171 u16 p[2];
user Joe Nagata0:e5197e77ab57 172 p[0] = dcid;
user Joe Nagata0:e5197e77ab57 173 p[1] = scid;
user Joe Nagata0:e5197e77ab57 174 return Send(L2CAP_DISCONN_REQ,_txid++,p,2);
user Joe Nagata0:e5197e77ab57 175}
user Joe Nagata0:e5197e77ab57 176
user Joe Nagata0:e5197e77ab57 177int BTDevice::ConfigureRequest(int dcid)
user Joe Nagata0:e5197e77ab57 178{
user Joe Nagata0:e5197e77ab57 179 u16 p[4];
user Joe Nagata0:e5197e77ab57 180 p[0] = dcid;
user Joe Nagata0:e5197e77ab57 181 p[1] = 0;
user Joe Nagata0:e5197e77ab57 182 p[2] = 0x0201; // Options
user Joe Nagata0:e5197e77ab57 183 p[3] = 0x02A0; // 672
user Joe Nagata0:e5197e77ab57 184 return Send(L2CAP_CONF_REQ,_txid++,p,4);
user Joe Nagata0:e5197e77ab57 185}
user Joe Nagata0:e5197e77ab57 186
user Joe Nagata0:e5197e77ab57 187int BTDevice::ConfigureResponse(u8 rxid, int dcid)
user Joe Nagata0:e5197e77ab57 188{
user Joe Nagata0:e5197e77ab57 189 u16 p[3];
user Joe Nagata0:e5197e77ab57 190 p[0] = dcid;
user Joe Nagata0:e5197e77ab57 191 p[1] = 0;
user Joe Nagata0:e5197e77ab57 192 p[2] = 0;
user Joe Nagata0:e5197e77ab57 193 return Send(L2CAP_CONF_RSP,rxid,p,3);
user Joe Nagata0:e5197e77ab57 194}
user Joe Nagata0:e5197e77ab57 195
user Joe Nagata0:e5197e77ab57 196int BTDevice::DisconnectResponse(u8 rxid, int scid, int dcid)
user Joe Nagata0:e5197e77ab57 197{
user Joe Nagata0:e5197e77ab57 198 u16 p[2];
user Joe Nagata0:e5197e77ab57 199 p[0] = dcid;
user Joe Nagata0:e5197e77ab57 200 p[1] = scid;
user Joe Nagata0:e5197e77ab57 201 return Send(L2CAP_DISCONN_RSP,rxid,p,2);
user Joe Nagata0:e5197e77ab57 202}
user Joe Nagata0:e5197e77ab57 203
user Joe Nagata0:e5197e77ab57 204void BTDevice::Control(const u8* data, int len)
user Joe Nagata0:e5197e77ab57 205{
user Joe Nagata0:e5197e77ab57 206 int cc = data[8];
user Joe Nagata0:e5197e77ab57 207 printf(L2CAP_ComandCodeStr(cc));
user Joe Nagata0:e5197e77ab57 208 int result = LE16(data+16);
user Joe Nagata0:e5197e77ab57 209 printf(" Result %d\n",result);
user Joe Nagata0:e5197e77ab57 210 switch (cc)
user Joe Nagata0:e5197e77ab57 211 {
user Joe Nagata0:e5197e77ab57 212 case L2CAP_COMMAND_REJ:
user Joe Nagata0:e5197e77ab57 213 break;
user Joe Nagata0:e5197e77ab57 214 case L2CAP_CONN_REQ:
user Joe Nagata0:e5197e77ab57 215 break;
user Joe Nagata0:e5197e77ab57 216
user Joe Nagata0:e5197e77ab57 217 // Response to our initial connect from Remote
user Joe Nagata0:e5197e77ab57 218 case L2CAP_CONN_RSP:
user Joe Nagata0:e5197e77ab57 219 {
user Joe Nagata0:e5197e77ab57 220 if (result == 0)
user Joe Nagata0:e5197e77ab57 221 {
user Joe Nagata0:e5197e77ab57 222 int dcid = LE16(data+12);
user Joe Nagata0:e5197e77ab57 223 int scid = LE16(data+14);
user Joe Nagata0:e5197e77ab57 224 L2CAPSocket* s = SCIDToSocket(scid);
user Joe Nagata0:e5197e77ab57 225 if (s)
user Joe Nagata0:e5197e77ab57 226 {
user Joe Nagata0:e5197e77ab57 227 s->dcid = dcid;
user Joe Nagata0:e5197e77ab57 228 ConfigureRequest(dcid);
user Joe Nagata0:e5197e77ab57 229 }
user Joe Nagata0:e5197e77ab57 230 } else
user Joe Nagata0:e5197e77ab57 231 printf("Connect failed?\n");
user Joe Nagata0:e5197e77ab57 232 }
user Joe Nagata0:e5197e77ab57 233 break;
user Joe Nagata0:e5197e77ab57 234
user Joe Nagata0:e5197e77ab57 235 case L2CAP_CONF_RSP:
user Joe Nagata0:e5197e77ab57 236 {
user Joe Nagata0:e5197e77ab57 237 int scid = LE16(data+12);
user Joe Nagata0:e5197e77ab57 238 SocketInternal* s = (SocketInternal*)SCIDToSocket(scid);
user Joe Nagata0:e5197e77ab57 239 if (s)
user Joe Nagata0:e5197e77ab57 240 s->SetState(SocketState_Open);
user Joe Nagata0:e5197e77ab57 241 }
user Joe Nagata0:e5197e77ab57 242 break;
user Joe Nagata0:e5197e77ab57 243
user Joe Nagata0:e5197e77ab57 244 case L2CAP_CONF_REQ:
user Joe Nagata0:e5197e77ab57 245 {
user Joe Nagata0:e5197e77ab57 246 int scid = LE16(data+12);
user Joe Nagata0:e5197e77ab57 247 L2CAPSocket* s = SCIDToSocket(scid);
user Joe Nagata0:e5197e77ab57 248 if (s)
user Joe Nagata0:e5197e77ab57 249 ConfigureResponse(data[9],s->dcid);
user Joe Nagata0:e5197e77ab57 250 }
user Joe Nagata0:e5197e77ab57 251 break;
user Joe Nagata0:e5197e77ab57 252 }
user Joe Nagata0:e5197e77ab57 253}
user Joe Nagata0:e5197e77ab57 254
user Joe Nagata0:e5197e77ab57 255void BTDevice::ACLRecv(const u8* data, int len)
user Joe Nagata0:e5197e77ab57 256{
user Joe Nagata0:e5197e77ab57 257 // printfBytes("L2CP",data,16);
user Joe Nagata0:e5197e77ab57 258 int handle = LE16(data);
user Joe Nagata0:e5197e77ab57 259 if (handle != (0x2000 | _handle))
user Joe Nagata0:e5197e77ab57 260 return;
user Joe Nagata0:e5197e77ab57 261
user Joe Nagata0:e5197e77ab57 262 int cid = LE16(data+6);
user Joe Nagata0:e5197e77ab57 263 if (cid == 1)
user Joe Nagata0:e5197e77ab57 264 {
user Joe Nagata0:e5197e77ab57 265 Control(data,len);
user Joe Nagata0:e5197e77ab57 266 return;
user Joe Nagata0:e5197e77ab57 267 }
user Joe Nagata0:e5197e77ab57 268
user Joe Nagata0:e5197e77ab57 269 SocketInternal* s = (SocketInternal*)SCIDToSocket(cid);
user Joe Nagata0:e5197e77ab57 270 if (s)
user Joe Nagata0:e5197e77ab57 271 s->Recv(data+8,LE16(data+2)-4);
user Joe Nagata0:e5197e77ab57 272 else
user Joe Nagata0:e5197e77ab57 273 printf("Bad event cid %d\n",cid);
user Joe Nagata0:e5197e77ab57 274}