xref: /haiku/src/kits/bluetooth/CommandManager.cpp (revision 350458a6baa20c4e615a3f627629551ac99cd614)
132c01b55SOliver Ruiz Dorantes /*
232c01b55SOliver Ruiz Dorantes  * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
332c01b55SOliver Ruiz Dorantes  *
432c01b55SOliver Ruiz Dorantes  * All rights reserved. Distributed under the terms of the MIT License.
532c01b55SOliver Ruiz Dorantes  *
632c01b55SOliver Ruiz Dorantes  */
732c01b55SOliver Ruiz Dorantes 
832c01b55SOliver Ruiz Dorantes 
932c01b55SOliver Ruiz Dorantes #include <bluetooth/bluetooth.h>
1032c01b55SOliver Ruiz Dorantes #include <bluetooth/HCI/btHCI_command.h>
1132c01b55SOliver Ruiz Dorantes 
1232c01b55SOliver Ruiz Dorantes #include <malloc.h>
1332c01b55SOliver Ruiz Dorantes 
1432c01b55SOliver Ruiz Dorantes #include "CommandManager.h"
1532c01b55SOliver Ruiz Dorantes 
1632c01b55SOliver Ruiz Dorantes 
1732c01b55SOliver Ruiz Dorantes inline void* buildCommand(uint8 ogf, uint8 ocf, void** param, size_t psize, size_t* outsize)
1832c01b55SOliver Ruiz Dorantes {
1932c01b55SOliver Ruiz Dorantes 	struct hci_command_header* header;
2032c01b55SOliver Ruiz Dorantes 
2132c01b55SOliver Ruiz Dorantes #ifdef BT_IOCTLS_PASS_SIZE
2232c01b55SOliver Ruiz Dorantes     header = (struct hci_command_header*) malloc(psize + sizeof(struct hci_command_header));
2332c01b55SOliver Ruiz Dorantes 	*outsize = psize + sizeof(struct hci_command_header);
2432c01b55SOliver Ruiz Dorantes #else
2532c01b55SOliver Ruiz Dorantes 	size_t* size = (size_t*)malloc(psize + sizeof(struct hci_command_header) + sizeof(size_t));
2632c01b55SOliver Ruiz Dorantes 	*outsize = psize + sizeof(struct hci_command_header) + sizeof(size_t);
2732c01b55SOliver Ruiz Dorantes 
2832c01b55SOliver Ruiz Dorantes     *size = psize + sizeof(struct hci_command_header);
2932c01b55SOliver Ruiz Dorantes     header = (struct hci_command_header*) (((uint8*)size)+4);
3032c01b55SOliver Ruiz Dorantes #endif
3132c01b55SOliver Ruiz Dorantes 
3232c01b55SOliver Ruiz Dorantes 
3332c01b55SOliver Ruiz Dorantes     if (header != NULL) {
3432c01b55SOliver Ruiz Dorantes 
3532c01b55SOliver Ruiz Dorantes         header->opcode = B_HOST_TO_LENDIAN_INT16(PACK_OPCODE(ogf, ocf));
3632c01b55SOliver Ruiz Dorantes         header->clen = psize;
3732c01b55SOliver Ruiz Dorantes 
3832c01b55SOliver Ruiz Dorantes         if (param != NULL && psize != 0) {
3932c01b55SOliver Ruiz Dorantes             *param = ((uint8*)header) + sizeof(struct hci_command_header);
4032c01b55SOliver Ruiz Dorantes         }
4132c01b55SOliver Ruiz Dorantes     }
4232c01b55SOliver Ruiz Dorantes #ifdef BT_IOCTLS_PASS_SIZE
4332c01b55SOliver Ruiz Dorantes     return header;
4432c01b55SOliver Ruiz Dorantes #else
4532c01b55SOliver Ruiz Dorantes     return (void*)size;
4632c01b55SOliver Ruiz Dorantes #endif
4732c01b55SOliver Ruiz Dorantes }
4832c01b55SOliver Ruiz Dorantes 
4932c01b55SOliver Ruiz Dorantes 
5032c01b55SOliver Ruiz Dorantes #if 0
5132c01b55SOliver Ruiz Dorantes #pragma mark - CONTROL BASEBAND -
5232c01b55SOliver Ruiz Dorantes #endif
5332c01b55SOliver Ruiz Dorantes 
5432c01b55SOliver Ruiz Dorantes 
5532c01b55SOliver Ruiz Dorantes void* buildReset(size_t* outsize)
5632c01b55SOliver Ruiz Dorantes {
5732c01b55SOliver Ruiz Dorantes     return buildCommand(OGF_CONTROL_BASEBAND, OCF_RESET, NULL, 0, outsize);
5832c01b55SOliver Ruiz Dorantes }
5932c01b55SOliver Ruiz Dorantes 
6032c01b55SOliver Ruiz Dorantes 
6132c01b55SOliver Ruiz Dorantes void* buildReadLocalName(size_t* outsize)
6232c01b55SOliver Ruiz Dorantes {
6332c01b55SOliver Ruiz Dorantes     return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME, NULL, 0, outsize);
6432c01b55SOliver Ruiz Dorantes }
6532c01b55SOliver Ruiz Dorantes 
6632c01b55SOliver Ruiz Dorantes 
67631aa548SOliver Ruiz Dorantes void* buildWriteScan(uint8 scanmode, size_t* outsize)
68631aa548SOliver Ruiz Dorantes {
69631aa548SOliver Ruiz Dorantes     struct hci_write_scan_enable* param;
70631aa548SOliver Ruiz Dorantes 	void* command = buildCommand(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE, (void**) &param, sizeof(struct hci_write_scan_enable), outsize);
71631aa548SOliver Ruiz Dorantes 
72631aa548SOliver Ruiz Dorantes 
73631aa548SOliver Ruiz Dorantes     if (command != NULL) {
74631aa548SOliver Ruiz Dorantes         param->scan = scanmode;
75631aa548SOliver Ruiz Dorantes     }
76631aa548SOliver Ruiz Dorantes 
77631aa548SOliver Ruiz Dorantes     return command;
78631aa548SOliver Ruiz Dorantes 
79631aa548SOliver Ruiz Dorantes }
80631aa548SOliver Ruiz Dorantes 
81631aa548SOliver Ruiz Dorantes 
82631aa548SOliver Ruiz Dorantes void* buildAuthEnable(uint8 auth, size_t* outsize)
83631aa548SOliver Ruiz Dorantes {
84631aa548SOliver Ruiz Dorantes     struct hci_write_authentication_enable* param;
85631aa548SOliver Ruiz Dorantes 	void* command = buildCommand(OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE, (void**) &param, sizeof(struct hci_write_authentication_enable), outsize);
86631aa548SOliver Ruiz Dorantes 
87631aa548SOliver Ruiz Dorantes 
88631aa548SOliver Ruiz Dorantes     if (command != NULL) {
89631aa548SOliver Ruiz Dorantes         param->authentication = auth;
90631aa548SOliver Ruiz Dorantes     }
91631aa548SOliver Ruiz Dorantes 
92631aa548SOliver Ruiz Dorantes     return command;
93631aa548SOliver Ruiz Dorantes 
94631aa548SOliver Ruiz Dorantes }
95631aa548SOliver Ruiz Dorantes 
96631aa548SOliver Ruiz Dorantes 
9732c01b55SOliver Ruiz Dorantes #if 0
9832c01b55SOliver Ruiz Dorantes #pragma mark - LINK CONTROL -
9932c01b55SOliver Ruiz Dorantes #endif
10032c01b55SOliver Ruiz Dorantes 
101631aa548SOliver Ruiz Dorantes void* buildCreateConnection(bdaddr_t bdaddr)
102631aa548SOliver Ruiz Dorantes {
103631aa548SOliver Ruiz Dorantes 	/*
104631aa548SOliver Ruiz Dorantes 	cm4.size = sizeof(struct hci_command_header)+sizeof(struct hci_cp_create_conn);
105631aa548SOliver Ruiz Dorantes 	cm4.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_LINK_CONTROL, OCF_CREATE_CONN));
106631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[0] = 0x92;
107631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[1] = 0xd3;
108631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[2] = 0xaf;
109631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[3] = 0xd9;
110631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[4] = 0x0a;
111631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[5] = 0x00;
112631aa548SOliver Ruiz Dorantes 	cm4.body.pkt_type = 0xFFFF;
113631aa548SOliver Ruiz Dorantes 	cm4.body.pscan_rep_mode = 1;
114631aa548SOliver Ruiz Dorantes 	cm4.body.pscan_mode = 0;
115631aa548SOliver Ruiz Dorantes 	cm4.body.clock_offset = 0xc7;
116631aa548SOliver Ruiz Dorantes 	cm4.body.role_switch = 1;
117631aa548SOliver Ruiz Dorantes 	cm4.header.clen = 13;
118631aa548SOliver Ruiz Dorantes 	ioctl(fd1, ISSUE_BT_COMMAND, &cm4, sizeof(cm4));
119631aa548SOliver Ruiz Dorantes 	*/
120631aa548SOliver Ruiz Dorantes 
121631aa548SOliver Ruiz Dorantes 	return NULL;
122631aa548SOliver Ruiz Dorantes }
123631aa548SOliver Ruiz Dorantes 
12432c01b55SOliver Ruiz Dorantes 
12532c01b55SOliver Ruiz Dorantes void* buildRemoteNameRequest(bdaddr_t bdaddr,uint8 pscan_rep_mode, uint16 clock_offset, size_t* outsize)
12632c01b55SOliver Ruiz Dorantes {
12732c01b55SOliver Ruiz Dorantes 
12832c01b55SOliver Ruiz Dorantes     struct hci_remote_name_request* param;
12932c01b55SOliver Ruiz Dorantes     void* command = buildCommand(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST, (void**) &param, sizeof(struct hci_remote_name_request), outsize);
13032c01b55SOliver Ruiz Dorantes 
13132c01b55SOliver Ruiz Dorantes     if (command != NULL) {
13232c01b55SOliver Ruiz Dorantes         param->bdaddr = bdaddr;
13332c01b55SOliver Ruiz Dorantes         param->pscan_rep_mode = pscan_rep_mode;
13432c01b55SOliver Ruiz Dorantes         param->clock_offset = clock_offset;
13532c01b55SOliver Ruiz Dorantes     }
13632c01b55SOliver Ruiz Dorantes 
13732c01b55SOliver Ruiz Dorantes     return command;
13832c01b55SOliver Ruiz Dorantes }
13932c01b55SOliver Ruiz Dorantes 
14032c01b55SOliver Ruiz Dorantes 
14132c01b55SOliver Ruiz Dorantes void* buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize)
14232c01b55SOliver Ruiz Dorantes {
14332c01b55SOliver Ruiz Dorantes 
14432c01b55SOliver Ruiz Dorantes     struct hci_cp_inquiry* param;
14532c01b55SOliver Ruiz Dorantes     void* command = buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY, (void**) &param, sizeof(struct hci_cp_inquiry), outsize);
14632c01b55SOliver Ruiz Dorantes 
14732c01b55SOliver Ruiz Dorantes     if (command != NULL) {
14832c01b55SOliver Ruiz Dorantes 
14932c01b55SOliver Ruiz Dorantes 	param->lap[2] = (lap >> 16) & 0xFF;
15032c01b55SOliver Ruiz Dorantes 	param->lap[1] = (lap >>  8) & 0xFF;
15132c01b55SOliver Ruiz Dorantes     	param->lap[0] = (lap >>  0) & 0xFF;
15232c01b55SOliver Ruiz Dorantes     	param->length = length;
15332c01b55SOliver Ruiz Dorantes     	param->num_rsp = num_rsp;
154*350458a6SOliver Ruiz Dorantes     }
155*350458a6SOliver Ruiz Dorantes 
156*350458a6SOliver Ruiz Dorantes     return command;
157*350458a6SOliver Ruiz Dorantes }
158*350458a6SOliver Ruiz Dorantes 
159*350458a6SOliver Ruiz Dorantes void* buildInquiryCancel(size_t* outsize)
160*350458a6SOliver Ruiz Dorantes {
161*350458a6SOliver Ruiz Dorantes 
162*350458a6SOliver Ruiz Dorantes     return buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL, NULL, 0, outsize);
163*350458a6SOliver Ruiz Dorantes 
164*350458a6SOliver Ruiz Dorantes }
165*350458a6SOliver Ruiz Dorantes 
166*350458a6SOliver Ruiz Dorantes 
167*350458a6SOliver Ruiz Dorantes void* buildPinCodeRequestReply(bdaddr_t bdaddr, uint8 length, char pincode[16], size_t* outsize)
168*350458a6SOliver Ruiz Dorantes {
169*350458a6SOliver Ruiz Dorantes 
170*350458a6SOliver Ruiz Dorantes     struct hci_cp_pin_code_reply* param;
171*350458a6SOliver Ruiz Dorantes 
172*350458a6SOliver Ruiz Dorantes     if (length > HCI_PIN_SIZE)  // PinCode cannot be longer than 16
173*350458a6SOliver Ruiz Dorantes 	return NULL;
174*350458a6SOliver Ruiz Dorantes 
175*350458a6SOliver Ruiz Dorantes     void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY, (void**) &param, sizeof(struct hci_cp_pin_code_reply), outsize);
176*350458a6SOliver Ruiz Dorantes 
177*350458a6SOliver Ruiz Dorantes     if (command != NULL) {
178*350458a6SOliver Ruiz Dorantes 
179*350458a6SOliver Ruiz Dorantes 	param->bdaddr = bdaddr;
180*350458a6SOliver Ruiz Dorantes 	param->pin_len = length;
181*350458a6SOliver Ruiz Dorantes     	memcpy(&param->pin_code, pincode, length);
182*350458a6SOliver Ruiz Dorantes 
183*350458a6SOliver Ruiz Dorantes     }
184*350458a6SOliver Ruiz Dorantes 
185*350458a6SOliver Ruiz Dorantes     return command;
186*350458a6SOliver Ruiz Dorantes }
187*350458a6SOliver Ruiz Dorantes 
188*350458a6SOliver Ruiz Dorantes 
189*350458a6SOliver Ruiz Dorantes void* buildPinCodeRequestNegativeReply(bdaddr_t bdaddr, uint8 length, char pincode[16], size_t* outsize)
190*350458a6SOliver Ruiz Dorantes {
191*350458a6SOliver Ruiz Dorantes 
192*350458a6SOliver Ruiz Dorantes     struct hci_cp_pin_code_neg_reply* param;
193*350458a6SOliver Ruiz Dorantes 
194*350458a6SOliver Ruiz Dorantes     void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY,
195*350458a6SOliver Ruiz Dorantes                                  (void**) &param, sizeof(struct hci_cp_pin_code_neg_reply), outsize);
196*350458a6SOliver Ruiz Dorantes 
197*350458a6SOliver Ruiz Dorantes     if (command != NULL) {
198*350458a6SOliver Ruiz Dorantes 
199*350458a6SOliver Ruiz Dorantes 	param->bdaddr = bdaddr;
200*350458a6SOliver Ruiz Dorantes 
20132c01b55SOliver Ruiz Dorantes     }
20232c01b55SOliver Ruiz Dorantes 
20332c01b55SOliver Ruiz Dorantes     return command;
20432c01b55SOliver Ruiz Dorantes }
20532c01b55SOliver Ruiz Dorantes 
20632c01b55SOliver Ruiz Dorantes 
20732c01b55SOliver Ruiz Dorantes #if 0
20832c01b55SOliver Ruiz Dorantes #pragma mark - INFORMATIONAL_PARAM -
20932c01b55SOliver Ruiz Dorantes #endif
21032c01b55SOliver Ruiz Dorantes 
21132c01b55SOliver Ruiz Dorantes 
21232c01b55SOliver Ruiz Dorantes void* buildReadBufferSize(size_t* outsize)
21332c01b55SOliver Ruiz Dorantes {
21432c01b55SOliver Ruiz Dorantes     return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE, NULL, 0, outsize);
21532c01b55SOliver Ruiz Dorantes }
21632c01b55SOliver Ruiz Dorantes 
21732c01b55SOliver Ruiz Dorantes 
21832c01b55SOliver Ruiz Dorantes void* buildReadBdAddr(size_t* outsize)
21932c01b55SOliver Ruiz Dorantes {
22032c01b55SOliver Ruiz Dorantes 	return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR, NULL, 0, outsize);
22132c01b55SOliver Ruiz Dorantes }
222631aa548SOliver Ruiz Dorantes 
223631aa548SOliver Ruiz Dorantes 
224631aa548SOliver Ruiz Dorantes 
225631aa548SOliver Ruiz Dorantes 
226