xref: /haiku/src/kits/bluetooth/CommandManager.cpp (revision 4079af86ca032f58fb1c97e5433e95815b16ebca)
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>
13*4079af86SRene Gollent #include <string.h>
1432c01b55SOliver Ruiz Dorantes 
1532c01b55SOliver Ruiz Dorantes #include "CommandManager.h"
1632c01b55SOliver Ruiz Dorantes 
1732c01b55SOliver Ruiz Dorantes 
1832c01b55SOliver Ruiz Dorantes inline void* buildCommand(uint8 ogf, uint8 ocf, void** param, size_t psize, size_t* outsize)
1932c01b55SOliver Ruiz Dorantes {
2032c01b55SOliver Ruiz Dorantes 	struct hci_command_header* header;
2132c01b55SOliver Ruiz Dorantes 
2232c01b55SOliver Ruiz Dorantes #ifdef BT_IOCTLS_PASS_SIZE
2332c01b55SOliver Ruiz Dorantes     header = (struct hci_command_header*) malloc(psize + sizeof(struct hci_command_header));
2432c01b55SOliver Ruiz Dorantes 	*outsize = psize + sizeof(struct hci_command_header);
2532c01b55SOliver Ruiz Dorantes #else
2632c01b55SOliver Ruiz Dorantes 	size_t* size = (size_t*)malloc(psize + sizeof(struct hci_command_header) + sizeof(size_t));
2732c01b55SOliver Ruiz Dorantes 	*outsize = psize + sizeof(struct hci_command_header) + sizeof(size_t);
2832c01b55SOliver Ruiz Dorantes 
2932c01b55SOliver Ruiz Dorantes     *size = psize + sizeof(struct hci_command_header);
3032c01b55SOliver Ruiz Dorantes     header = (struct hci_command_header*) (((uint8*)size)+4);
3132c01b55SOliver Ruiz Dorantes #endif
3232c01b55SOliver Ruiz Dorantes 
3332c01b55SOliver Ruiz Dorantes 
3432c01b55SOliver Ruiz Dorantes     if (header != NULL) {
3532c01b55SOliver Ruiz Dorantes 
3632c01b55SOliver Ruiz Dorantes         header->opcode = B_HOST_TO_LENDIAN_INT16(PACK_OPCODE(ogf, ocf));
3732c01b55SOliver Ruiz Dorantes         header->clen = psize;
3832c01b55SOliver Ruiz Dorantes 
3932c01b55SOliver Ruiz Dorantes         if (param != NULL && psize != 0) {
4032c01b55SOliver Ruiz Dorantes             *param = ((uint8*)header) + sizeof(struct hci_command_header);
4132c01b55SOliver Ruiz Dorantes         }
4232c01b55SOliver Ruiz Dorantes     }
4332c01b55SOliver Ruiz Dorantes #ifdef BT_IOCTLS_PASS_SIZE
4432c01b55SOliver Ruiz Dorantes     return header;
4532c01b55SOliver Ruiz Dorantes #else
4632c01b55SOliver Ruiz Dorantes     return (void*)size;
4732c01b55SOliver Ruiz Dorantes #endif
4832c01b55SOliver Ruiz Dorantes }
4932c01b55SOliver Ruiz Dorantes 
5032c01b55SOliver Ruiz Dorantes 
5132c01b55SOliver Ruiz Dorantes #if 0
5232c01b55SOliver Ruiz Dorantes #pragma mark - CONTROL BASEBAND -
5332c01b55SOliver Ruiz Dorantes #endif
5432c01b55SOliver Ruiz Dorantes 
5532c01b55SOliver Ruiz Dorantes 
5632c01b55SOliver Ruiz Dorantes void* buildReset(size_t* outsize)
5732c01b55SOliver Ruiz Dorantes {
5832c01b55SOliver Ruiz Dorantes     return buildCommand(OGF_CONTROL_BASEBAND, OCF_RESET, NULL, 0, outsize);
5932c01b55SOliver Ruiz Dorantes }
6032c01b55SOliver Ruiz Dorantes 
6132c01b55SOliver Ruiz Dorantes 
6232c01b55SOliver Ruiz Dorantes void* buildReadLocalName(size_t* outsize)
6332c01b55SOliver Ruiz Dorantes {
6432c01b55SOliver Ruiz Dorantes     return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME, NULL, 0, outsize);
6532c01b55SOliver Ruiz Dorantes }
6632c01b55SOliver Ruiz Dorantes 
6732c01b55SOliver Ruiz Dorantes 
68631aa548SOliver Ruiz Dorantes void* buildWriteScan(uint8 scanmode, size_t* outsize)
69631aa548SOliver Ruiz Dorantes {
70631aa548SOliver Ruiz Dorantes     struct hci_write_scan_enable* param;
71631aa548SOliver Ruiz Dorantes 	void* command = buildCommand(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE, (void**) &param, sizeof(struct hci_write_scan_enable), outsize);
72631aa548SOliver Ruiz Dorantes 
73631aa548SOliver Ruiz Dorantes 
74631aa548SOliver Ruiz Dorantes     if (command != NULL) {
75631aa548SOliver Ruiz Dorantes         param->scan = scanmode;
76631aa548SOliver Ruiz Dorantes     }
77631aa548SOliver Ruiz Dorantes 
78631aa548SOliver Ruiz Dorantes     return command;
79631aa548SOliver Ruiz Dorantes 
80631aa548SOliver Ruiz Dorantes }
81631aa548SOliver Ruiz Dorantes 
82631aa548SOliver Ruiz Dorantes 
83631aa548SOliver Ruiz Dorantes void* buildAuthEnable(uint8 auth, size_t* outsize)
84631aa548SOliver Ruiz Dorantes {
85631aa548SOliver Ruiz Dorantes     struct hci_write_authentication_enable* param;
86631aa548SOliver Ruiz Dorantes 	void* command = buildCommand(OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE, (void**) &param, sizeof(struct hci_write_authentication_enable), outsize);
87631aa548SOliver Ruiz Dorantes 
88631aa548SOliver Ruiz Dorantes 
89631aa548SOliver Ruiz Dorantes     if (command != NULL) {
90631aa548SOliver Ruiz Dorantes         param->authentication = auth;
91631aa548SOliver Ruiz Dorantes     }
92631aa548SOliver Ruiz Dorantes 
93631aa548SOliver Ruiz Dorantes     return command;
94631aa548SOliver Ruiz Dorantes 
95631aa548SOliver Ruiz Dorantes }
96631aa548SOliver Ruiz Dorantes 
97631aa548SOliver Ruiz Dorantes 
9832c01b55SOliver Ruiz Dorantes #if 0
9932c01b55SOliver Ruiz Dorantes #pragma mark - LINK CONTROL -
10032c01b55SOliver Ruiz Dorantes #endif
10132c01b55SOliver Ruiz Dorantes 
102631aa548SOliver Ruiz Dorantes void* buildCreateConnection(bdaddr_t bdaddr)
103631aa548SOliver Ruiz Dorantes {
104631aa548SOliver Ruiz Dorantes 	/*
105631aa548SOliver Ruiz Dorantes 	cm4.size = sizeof(struct hci_command_header)+sizeof(struct hci_cp_create_conn);
106631aa548SOliver Ruiz Dorantes 	cm4.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_LINK_CONTROL, OCF_CREATE_CONN));
107631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[0] = 0x92;
108631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[1] = 0xd3;
109631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[2] = 0xaf;
110631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[3] = 0xd9;
111631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[4] = 0x0a;
112631aa548SOliver Ruiz Dorantes 	cm4.body.bdaddr.b[5] = 0x00;
113631aa548SOliver Ruiz Dorantes 	cm4.body.pkt_type = 0xFFFF;
114631aa548SOliver Ruiz Dorantes 	cm4.body.pscan_rep_mode = 1;
115631aa548SOliver Ruiz Dorantes 	cm4.body.pscan_mode = 0;
116631aa548SOliver Ruiz Dorantes 	cm4.body.clock_offset = 0xc7;
117631aa548SOliver Ruiz Dorantes 	cm4.body.role_switch = 1;
118631aa548SOliver Ruiz Dorantes 	cm4.header.clen = 13;
119631aa548SOliver Ruiz Dorantes 	ioctl(fd1, ISSUE_BT_COMMAND, &cm4, sizeof(cm4));
120631aa548SOliver Ruiz Dorantes 	*/
121631aa548SOliver Ruiz Dorantes 
122631aa548SOliver Ruiz Dorantes 	return NULL;
123631aa548SOliver Ruiz Dorantes }
124631aa548SOliver Ruiz Dorantes 
12532c01b55SOliver Ruiz Dorantes 
12632c01b55SOliver Ruiz Dorantes void* buildRemoteNameRequest(bdaddr_t bdaddr,uint8 pscan_rep_mode, uint16 clock_offset, size_t* outsize)
12732c01b55SOliver Ruiz Dorantes {
12832c01b55SOliver Ruiz Dorantes 
12932c01b55SOliver Ruiz Dorantes     struct hci_remote_name_request* param;
13032c01b55SOliver Ruiz Dorantes     void* command = buildCommand(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST, (void**) &param, sizeof(struct hci_remote_name_request), outsize);
13132c01b55SOliver Ruiz Dorantes 
13232c01b55SOliver Ruiz Dorantes     if (command != NULL) {
13332c01b55SOliver Ruiz Dorantes         param->bdaddr = bdaddr;
13432c01b55SOliver Ruiz Dorantes         param->pscan_rep_mode = pscan_rep_mode;
13532c01b55SOliver Ruiz Dorantes         param->clock_offset = clock_offset;
13632c01b55SOliver Ruiz Dorantes     }
13732c01b55SOliver Ruiz Dorantes 
13832c01b55SOliver Ruiz Dorantes     return command;
13932c01b55SOliver Ruiz Dorantes }
14032c01b55SOliver Ruiz Dorantes 
14132c01b55SOliver Ruiz Dorantes 
14232c01b55SOliver Ruiz Dorantes void* buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize)
14332c01b55SOliver Ruiz Dorantes {
14432c01b55SOliver Ruiz Dorantes 
14532c01b55SOliver Ruiz Dorantes     struct hci_cp_inquiry* param;
14632c01b55SOliver Ruiz Dorantes     void* command = buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY, (void**) &param, sizeof(struct hci_cp_inquiry), outsize);
14732c01b55SOliver Ruiz Dorantes 
14832c01b55SOliver Ruiz Dorantes     if (command != NULL) {
14932c01b55SOliver Ruiz Dorantes 
15032c01b55SOliver Ruiz Dorantes 		param->lap[2] = (lap >> 16) & 0xFF;
15132c01b55SOliver Ruiz Dorantes 		param->lap[1] = (lap >>  8) & 0xFF;
15232c01b55SOliver Ruiz Dorantes     	param->lap[0] = (lap >>  0) & 0xFF;
15332c01b55SOliver Ruiz Dorantes     	param->length = length;
15432c01b55SOliver Ruiz Dorantes     	param->num_rsp = num_rsp;
155350458a6SOliver Ruiz Dorantes     }
156350458a6SOliver Ruiz Dorantes 
157350458a6SOliver Ruiz Dorantes     return command;
158350458a6SOliver Ruiz Dorantes }
159350458a6SOliver Ruiz Dorantes 
160350458a6SOliver Ruiz Dorantes void* buildInquiryCancel(size_t* outsize)
161350458a6SOliver Ruiz Dorantes {
162350458a6SOliver Ruiz Dorantes 
163350458a6SOliver Ruiz Dorantes     return buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL, NULL, 0, outsize);
164350458a6SOliver Ruiz Dorantes 
165350458a6SOliver Ruiz Dorantes }
166350458a6SOliver Ruiz Dorantes 
167350458a6SOliver Ruiz Dorantes 
168350458a6SOliver Ruiz Dorantes void* buildPinCodeRequestReply(bdaddr_t bdaddr, uint8 length, char pincode[16], size_t* outsize)
169350458a6SOliver Ruiz Dorantes {
170350458a6SOliver Ruiz Dorantes 
171350458a6SOliver Ruiz Dorantes     struct hci_cp_pin_code_reply* param;
172350458a6SOliver Ruiz Dorantes 
173350458a6SOliver Ruiz Dorantes     if (length > HCI_PIN_SIZE)  // PinCode cannot be longer than 16
174350458a6SOliver Ruiz Dorantes 	return NULL;
175350458a6SOliver Ruiz Dorantes 
176350458a6SOliver Ruiz Dorantes     void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY, (void**) &param, sizeof(struct hci_cp_pin_code_reply), outsize);
177350458a6SOliver Ruiz Dorantes 
178350458a6SOliver Ruiz Dorantes     if (command != NULL) {
179350458a6SOliver Ruiz Dorantes 
180350458a6SOliver Ruiz Dorantes 	param->bdaddr = bdaddr;
181350458a6SOliver Ruiz Dorantes 	param->pin_len = length;
182350458a6SOliver Ruiz Dorantes     	memcpy(&param->pin_code, pincode, length);
183350458a6SOliver Ruiz Dorantes 
184350458a6SOliver Ruiz Dorantes     }
185350458a6SOliver Ruiz Dorantes 
186350458a6SOliver Ruiz Dorantes     return command;
187350458a6SOliver Ruiz Dorantes }
188350458a6SOliver Ruiz Dorantes 
189350458a6SOliver Ruiz Dorantes 
1900df89492SOliver Ruiz Dorantes void* buildPinCodeRequestNegativeReply(bdaddr_t bdaddr, size_t* outsize)
191350458a6SOliver Ruiz Dorantes {
192350458a6SOliver Ruiz Dorantes 
193350458a6SOliver Ruiz Dorantes     struct hci_cp_pin_code_neg_reply* param;
194350458a6SOliver Ruiz Dorantes 
195350458a6SOliver Ruiz Dorantes     void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY,
196350458a6SOliver Ruiz Dorantes                                  (void**) &param, sizeof(struct hci_cp_pin_code_neg_reply), outsize);
197350458a6SOliver Ruiz Dorantes 
198350458a6SOliver Ruiz Dorantes     if (command != NULL) {
199350458a6SOliver Ruiz Dorantes 
200350458a6SOliver Ruiz Dorantes 		param->bdaddr = bdaddr;
201350458a6SOliver Ruiz Dorantes 
20232c01b55SOliver Ruiz Dorantes     }
20332c01b55SOliver Ruiz Dorantes 
20432c01b55SOliver Ruiz Dorantes     return command;
20532c01b55SOliver Ruiz Dorantes }
20632c01b55SOliver Ruiz Dorantes 
20732c01b55SOliver Ruiz Dorantes 
20832c01b55SOliver Ruiz Dorantes #if 0
20932c01b55SOliver Ruiz Dorantes #pragma mark - INFORMATIONAL_PARAM -
21032c01b55SOliver Ruiz Dorantes #endif
21132c01b55SOliver Ruiz Dorantes 
21232c01b55SOliver Ruiz Dorantes 
21332c01b55SOliver Ruiz Dorantes void* buildReadBufferSize(size_t* outsize)
21432c01b55SOliver Ruiz Dorantes {
21532c01b55SOliver Ruiz Dorantes     return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE, NULL, 0, outsize);
21632c01b55SOliver Ruiz Dorantes }
21732c01b55SOliver Ruiz Dorantes 
21832c01b55SOliver Ruiz Dorantes 
21932c01b55SOliver Ruiz Dorantes void* buildReadBdAddr(size_t* outsize)
22032c01b55SOliver Ruiz Dorantes {
22132c01b55SOliver Ruiz Dorantes 	return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR, NULL, 0, outsize);
22232c01b55SOliver Ruiz Dorantes }
223631aa548SOliver Ruiz Dorantes 
224631aa548SOliver Ruiz Dorantes 
225631aa548SOliver Ruiz Dorantes 
226631aa548SOliver Ruiz Dorantes 
227