1/* 2 * Copyright 2007-2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * Copyright 2008 Mika Lindqvist 4 * Copyright 2012 Fredrik Modéen [firstname]@[lastname].se 5 * All rights reserved. Distributed under the terms of the MIT License. 6 */ 7#ifndef _COMMAND_MANAGER_H 8#define _COMMAND_MANAGER_H 9 10#include <malloc.h> 11#include <string.h> 12 13#include <bluetooth/bluetooth.h> 14#include <bluetooth/bluetooth_error.h> 15#include <bluetooth/HCI/btHCI_command.h> 16#include <bluetooth/HCI/btHCI_event.h> 17 18#include <Message.h> 19#include <Messenger.h> 20 21#include <bluetoothserver_p.h> 22 23#define typed_command(type) type, sizeof(type) 24 25template <typename Type = void, int paramSize = 0, 26 int HeaderSize = HCI_COMMAND_HDR_SIZE> 27class BluetoothCommand { 28 29public: 30 BluetoothCommand(uint8 ogf, uint8 ocf) 31 { 32 fHeader = (struct hci_command_header*) fBuffer; 33 34 if (paramSize != 0) 35 fContent = (Type*)(fHeader + 1); 36 else 37 // avoid pointing outside in case of not having parameters 38 fContent = (Type*)fHeader; 39 40 fHeader->opcode = B_HOST_TO_LENDIAN_INT16(PACK_OPCODE(ogf, ocf)); 41 fHeader->clen = paramSize; 42 } 43 44 Type* 45 operator->() const 46 { 47 return fContent; 48 } 49 50 void* 51 Data() const 52 { 53 return (void*)fBuffer; 54 } 55 56 size_t Size() const 57 { 58 return HeaderSize + paramSize; 59 } 60 61private: 62 char fBuffer[paramSize + HeaderSize]; 63 Type* fContent; 64 struct hci_command_header* fHeader; 65}; 66 67 68status_t 69NonParameterCommandRequest(uint8 ofg, uint8 ocf, int32* result, hci_id hId, 70 BMessenger* messenger); 71 72template<typename PARAMETERCONTAINER, typename PARAMETERTYPE> 73status_t 74SingleParameterCommandRequest(uint8 ofg, uint8 ocf, PARAMETERTYPE parameter, 75 int32* result, hci_id hId, BMessenger* messenger) 76{ 77 int8 bt_status = BT_ERROR; 78 79 BluetoothCommand<typed_command(PARAMETERCONTAINER)> 80 simpleCommand(ofg, ocf); 81 82 simpleCommand->param = parameter; 83 84 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 85 BMessage reply; 86 87 simpleCommand->param = parameter; 88 89 request.AddInt32("hci_id", hId); 90 request.AddData("raw command", B_ANY_TYPE, simpleCommand.Data(), 91 simpleCommand.Size()); 92 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 93 request.AddInt16("opcodeExpected", PACK_OPCODE(ofg, ocf)); 94 95 if (messenger->SendMessage(&request, &reply) == B_OK) { 96 reply.FindInt8("status", &bt_status); 97 if (result != NULL) 98 reply.FindInt32("result", result); 99 } 100 101 return bt_status; 102} 103 104 105/* CONTROL BASEBAND */ 106void* buildReset(size_t* outsize); 107void* buildReadLocalName(size_t* outsize); 108void* buildReadScan(size_t* outsize); 109void* buildWriteScan(uint8 scanmode, size_t* outsize); 110void* buildReadClassOfDevice(size_t* outsize); 111 112/* LINK CONTROL */ 113void* buildRemoteNameRequest(bdaddr_t bdaddr, uint8 pscan_rep_mode, 114 uint16 clock_offset, size_t* outsize); 115void* buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize); 116void* buildInquiryCancel(size_t* outsize); 117void* buildPinCodeRequestReply(bdaddr_t bdaddr, uint8 length, char pincode[16], 118 size_t* outsize); 119void* buildPinCodeRequestNegativeReply(bdaddr_t bdaddr, size_t* outsize); 120void* buildAcceptConnectionRequest(bdaddr_t bdaddr, uint8 role, 121 size_t* outsize); 122void* buildRejectConnectionRequest(bdaddr_t bdaddr, size_t* outsize); 123 124/* OGF_INFORMATIONAL_PARAM */ 125void* buildReadLocalVersionInformation(size_t* outsize); 126void* buildReadBufferSize(size_t* outsize); 127void* buildReadBdAddr(size_t* outsize); 128 129#endif 130