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