Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: C12832 GPS GSM mbed
Fork of myBlueUSB_localfix by
TestShell.cpp
- Committer:
- nobukuma
- Date:
- 2013-12-07
- Revision:
- 0:003889bc474f
- Child:
- 2:9f25a7fa1a54
File content as of revision 0:003889bc474f:
/*
Copyright (c) 2010 Peter Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "mbed.h"
#include <vector>
#include "Utils.h"
#include "USBHost.h"
#include "hci.h"
#include "HCITransportUSB.h"
#include "RFCOMM.h"
#include "ftclasslibusbdevbt.h"
#include "sdp_data.h"
#include "sdp.h"
#include "btserial.h"
#include "neighbourhood.h"
/************************************************
TODO:
mtu and credits are completely unhandled - in progress
multiple rfcomm sessions should be possible - done
SDP would be nice - beta
multiple rfcomm channels are untested
decoupling of rfcomm and application - much better
packets are not reassembled - some are (HCI and ft application level)
disconnect and timeouts
************************************************/
#define DEBUG 1
int state = 0;
//int bulk = 0;
void printf(const BD_ADDR* addr) {
const u8* a = addr->addr;
printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
}
const char FtDevClass[3] = {0x00, 0x1F, 0x82 };
const char SerDevClass[3] = {4, 1, 0x00};
// Instance
//RFCOMMManager rfcomm_manager;
class application : public HCI {
BTDevice* devs[8];
int count, i, pending;
public:
// We have connected to a device
void ConnectionComplete(connection_info* info) {
printf("ConnectionComplete ");
BD_ADDR* a = &info->bdaddr;
printf(a);
printf("\n");
RemoteNameRequest(a);
for (i++; i < count; i++) {//find the next device to open
printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices
BD_ADDR* bd = &devs[i]->_info.bdaddr;
printf("Connecting to ");
printf(bd);
printf("\n");
pending++;
CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
printf("connection cmd was sent\n");
return;
}
}
//state = 1; //start the real application
}
void ConnectDevices() {
count = GetDevices(devs,8);//get pointers to all bluetooth devices
pending = 0;
for (i = 0; i < count; i++) {
printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
if (devs[i]->_handle == 0 /*&& memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0*/) {//or some other way to connect to RFCOMM devices
BD_ADDR* bd = &devs[i]->_info.bdaddr;
printf("Connecting to ");
printf(bd);
printf("\n");
pending++;
CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
printf("connection cmd was sent\n");
return;
}
}
if (pending == 0) state = 1;//for the case when there are no ft devices
}
virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len);
int csr_write_bd_addr(BD_ADDR *bdaddr, bool transient=true);
int csr_reset_device(bool transient=true);
} App; //application instance
extern "C" void mbed_reset();
void application::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv
unsigned char pin[] = "1234";
unsigned char newaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277)
// unsigned char newaddr[] = {0x57, 0x0a, 0x3d, 0x83, 0x15, 0x00};//original address of the cheap round BT dongle
printf("\x1b[%dm", 33);
switch (evt) {
case CALLBACK_READY:
printf("CALLBACK_READY\n");
printf("my address = ");
printf((BD_ADDR*)data);
if (memcmp(newaddr, data, 6) != 0) { //csr_write_bd_addr((BD_ADDR*)newaddr, false);
}
Inquiry();//start the second phase of the discovery
break;
case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here
printf("CALLBACK_INQUIRY_RESULT ");
printf((BD_ADDR*)data);
printf("\n");//data points to inquiry_info struct
// RemoteNameRequest((BD_ADDR*)data);
break;
case CALLBACK_INQUIRY_DONE:
printf("CALLBACK_INQUIRY_DONE\n");
neighbors = new neighbourhood(&App);
neighbors->read();
ConnectDevices();
break;
case CALLBACK_REMOTE_NAME: {
BD_ADDR* addr = (BD_ADDR*)data;
const char* name = (const char*)(data + 6);
printf(addr);
printf(" = % s\n",name);
pending--;
if (pending == 0) state = 1;
}
break;
case CALLBACK_CONNECTION_COMPLETE: {
connection_info *ci = (connection_info*)data;
if (ci->status>0) {
printf("Connection failed, status=0x%02X\n", ci->status);
break;
}
ConnectionComplete(ci);
printf("Going to open sdp socket\n");
L2CAPAddr addr;
memcpy(&addr.bdaddr, &ci->bdaddr, 6);
//int s = SDP.Open(&addr.hdr);
}
break;
case CALLBACK_PIN_REQ:
printf("Enter PIN for ");
printf((BD_ADDR*)data);
printf(" : submitting %s\n", pin);
//USBLoop(); wait(1.0); USBLoop();
//for(int k=0; k<2000000;k++) USBLoop();
PinCodeReply(data, pin);
break;
case CALLBACK_VENDOR:
printfBytes("Vendor Reply:", data, len);
//mbed_reset();
if (data[0] == 0xc2)
csr_reset_device(false);
break;
default:
printf("Unhandled HCI Callback %d\n", evt);
};
printf("\x1b[%dm", 0);
}
#define CSR_WRITE 0xFC00
int application::csr_write_bd_addr(BD_ADDR *bdaddr, bool transient) {
unsigned char cmd[] = { 0xc2,
0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70,
0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
if (transient)
cmd[15] = 0x08;
cmd[17] = bdaddr->addr[2];
cmd[18] = 0x00;
cmd[19] = bdaddr->addr[0];
cmd[20] = bdaddr->addr[1];
cmd[21] = bdaddr->addr[3];
cmd[22] = 0x00;
cmd[23] = bdaddr->addr[4];
cmd[24] = bdaddr->addr[5];
return SendCmd(CSR_WRITE, cmd, sizeof(cmd));
}
int application::csr_reset_device(bool transient) {
unsigned char cmd[] = { 0xc2, 0x02, 0x00, 0x09, 0x00,
0x00, 0x00, 0x01, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
if (transient)
cmd[7] = 0x02;
return SendCmd(CSR_WRITE, cmd, sizeof(cmd));
}
// these should be placed in the DMA SRAM
typedef struct {
u8 _hciBuffer[MAX_HCL_SIZE];
u8 _aclBuffer[MAX_ACL_SIZE];
} SRAMPlacement;
HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio
int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback
printf("Bluetooth inserted of %d\n",device);
u32 sramLen;
u8* sram = USBGetBuffer(&sramLen);
sram = (u8*)(((u32)sram + 1023) & ~1023);
SRAMPlacement* s = (SRAMPlacement*)sram;
_HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv
RegisterSocketHandler(SOCKET_L2CAP,&App); //register the application::hci as handler for L2CAP events
RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler
if (RegisterSocketHandler(SOCKET_SDP, &SDP))
printf("Could not register SDP socket type\n");
App.Open(&_HCITransportUSB);//the callback is virtual
App.Inquiry();//start discovery of BT devices phase 0
return 0;
}
DigitalOut led(LED1), loop(LED2);
int comm = 0;
btserial *incoming, *outgoing;
void echo(int socket, SocketState state, const u8* data, int len, void* userData) {
const u8 connack[] = { 0xbe, 0xef, 8, 'C','O','N','N','_','A','C','K', 0x11};
printf("Echo: socket %d, state %d, len=%d\n", socket, state, len);
if (state==SocketState_Open) {
if (len == 0) {
printf("Sending CONN_ACK\n");
Socket_Send(socket, connack, sizeof(connack));
} else {
//Socket_Send(socket, data, len);
printfBytes("echo:", data, len);
}
}
}
void TestShell() {
int n=0;
USBInit();
for (;;) {
switch (state) {
case 0: //inquiry and low-level connection
break;
case 1: {//initialisation
printf("Ready to open ports\n");
InitFtBtDeviceList();
int n = GetNrOfFtBtDevices();
printf("%d ft BT devices have been found\n", n);
if (n > 0) {
ftbtdev *d = GetFtUsbDeviceHandle(0);
if (d==0) printf("could not get device handle\n");
int sock = OpenFtBtDevice(d);
}
state = 2;
//comm = Socket_Listen(SOCKET_RFCOM, 1, echo, 0);
//incoming = new btserial(1);
}
break;
case 2://main loop
/* if (incoming->readable()>0){
int c= incoming->getc();
putc(c, stderr);
incoming->putc(c);
}
else if (incoming->readable()<0){
state = 3;
printf("end of session");
delete incoming;
}*/
break;
default:
break;
}
loop=1;
USBLoop();
loop=0;
n++;
if (n>=500000) {
n=0;
led = !led;
}
}
//printf("Dropped out of main loop!\n");
}
//********************************************************************************************************************************
