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 25 template <typename Type = void, int paramSize = 0, 26 int HeaderSize = HCI_COMMAND_HDR_SIZE> 27 class BluetoothCommand { 28 29 public: 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 61 private: 62 char fBuffer[paramSize + HeaderSize]; 63 Type* fContent; 64 struct hci_command_header* fHeader; 65 }; 66 67 68 status_t 69 NonParameterCommandRequest(uint8 ofg, uint8 ocf, int32* result, hci_id hId, 70 BMessenger* messenger); 71 72 template<typename PARAMETERCONTAINER, typename PARAMETERTYPE> 73 status_t 74 SingleParameterCommandRequest(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 */ 106 void* buildReset(size_t* outsize); 107 void* buildReadLocalName(size_t* outsize); 108 void* buildReadScan(size_t* outsize); 109 void* buildWriteScan(uint8 scanmode, size_t* outsize); 110 void* buildReadClassOfDevice(size_t* outsize); 111 112 /* LINK CONTROL */ 113 void* buildRemoteNameRequest(bdaddr_t bdaddr, uint8 pscan_rep_mode, 114 uint16 clock_offset, size_t* outsize); 115 void* buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize); 116 void* buildInquiryCancel(size_t* outsize); 117 void* buildPinCodeRequestReply(bdaddr_t bdaddr, uint8 length, char pincode[16], 118 size_t* outsize); 119 void* buildPinCodeRequestNegativeReply(bdaddr_t bdaddr, size_t* outsize); 120 void* buildAcceptConnectionRequest(bdaddr_t bdaddr, uint8 role, 121 size_t* outsize); 122 void* buildRejectConnectionRequest(bdaddr_t bdaddr, size_t* outsize); 123 124 /* OGF_INFORMATIONAL_PARAM */ 125 void* buildReadLocalVersionInformation(size_t* outsize); 126 void* buildReadBufferSize(size_t* outsize); 127 void* buildReadBdAddr(size_t* outsize); 128 129 #endif 130