]> rtime.felk.cvut.cz Git - tiny-bt.git/blob - src2/tiny_bt_hci_cmd.c
outgoing data packet was modified. Now I can send packet and receive it on second...
[tiny-bt.git] / src2 / tiny_bt_hci_cmd.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <unistd.h>
6 #include <stdint.h>
7 #include <fcntl.h>
8 #include <sys/poll.h>
9 #include "tiny_bt_hci_cmd.h"
10 #include "bt_hw.h"
11
12 /************************** hci command functions**************************/
13 int send_hci_inquiry_cmd(void)
14 {
15         inquiry_cp cmdp, *p_cmdp = &cmdp;
16         hci_cmd_request creq, *p_creq = &creq;
17         inq_time time = T14s40;
18         responce_num num = NUM_RSP_20; 
19         
20         memset(p_cmdp, 0, sizeof(cmdp));
21         p_cmdp->lap[0] = 0x33;
22         p_cmdp->lap[1] = 0x8b;
23         p_cmdp->lap[2] = 0x9e;
24         p_cmdp->length = time;
25         p_cmdp->num_rsp = num;
26         memset(p_creq, 0, sizeof(creq));
27         p_creq->OCF_OGF = INQUIRY_CMD_OP;
28         p_creq->p_cmdp = p_cmdp;
29         p_creq->cmdp_len = INQUIRY_CP_SIZE;
30         
31         if (send_cmd(p_creq) < 0) {
32                 perror("hci_inquiry_cmd wasn't sent\n");
33                 return -1;
34         }
35         return 0;
36 }
37 /* fill up the input parameter address pointer by one address*/
38 int send_hci_read_bd_addr_cmd(void)
39 {
40         hci_cmd_request creq, *p_creq = &creq;
41                 
42         memset(p_creq, 0, sizeof(creq));
43         p_creq->OCF_OGF = READ_BD_ADDR_CMD_OP;
44         p_creq->cmdp_len = 0;
45         
46         if (send_cmd(p_creq) < 0) {
47                 perror("hci_read_bd_addr wasn't sent\n");
48                 return -1;
49         }
50         return 0;
51 }
52
53 int send_hci_read_local_name_cmd(void)
54 {
55         hci_cmd_request creq, *p_creq = &creq;
56                 
57         memset(p_creq, 0, sizeof(creq));
58         p_creq->OCF_OGF = READ_LOCAL_NAME_CMD_OP;
59         p_creq->cmdp_len = 0;
60         
61         if (send_cmd(p_creq) < 0) {
62                 perror("hci_read_local_name_cmd wasn't sent\n");
63                 return -1;
64         }
65         return 0;
66 }
67
68 int send_hci_create_connection_cmd(bt_address *p_dest_addr)
69 {
70         create_conn_cp cmdp, *p_cmdp = &cmdp;
71         hci_cmd_request creq, *p_creq = &creq;
72         
73         memset(p_cmdp, 0, sizeof(cmdp));        
74         p_cmdp->bdaddr= *p_dest_addr;
75         p_cmdp->pkt_type = 0x0010;
76         p_cmdp->pscan_rep_mode = 0x01;
77         p_cmdp->pscan_mode = 0x00;
78         p_cmdp->clock_offset = 0xf000;
79         p_cmdp->role_switch = 0x00;
80         
81         memset(p_creq, 0, sizeof(creq));
82         p_creq->OCF_OGF = CREATE_CONNECTION_CMD_OP;
83         p_creq->p_cmdp = p_cmdp;
84         p_creq->cmdp_len = CREATE_CONN_CP_SIZE;
85         
86         if (send_cmd(p_creq) < 0) {
87                 perror("hci_create_connection_cmd wasn't sent\n");
88                 return -1;
89         }
90         return 0;       
91 }
92
93 int send_hci_accept_conn_req_cmd(bt_address *p_address)
94 {
95         accept_conn_req_cp cmdp, *p_cmdp = &cmdp;
96         hci_cmd_request creq, *p_creq = &creq;
97         
98         memset(p_cmdp, 0, sizeof(cmdp));
99         p_cmdp->bdaddr = *p_address;
100         p_cmdp->role = 0x01;
101         memset(p_creq, 0, sizeof(creq));
102         p_creq->OCF_OGF = ACCEPT_CONNECTION_REQ_OP;
103         p_creq->p_cmdp = p_cmdp;
104         p_creq->cmdp_len = ACCEPT_CONN_REQ_CP_SIZE;
105         
106         if (send_cmd(p_creq) < 0) {
107                 perror("hci_accept_conn_req_cmd wasn't sent\n");
108                 return -1;
109         }
110         return 0;
111 }
112
113 int send_hci_disconnect_cmd(__u16 handle)
114 {
115         disconnect_cp cmdp, *p_cmdp = &cmdp;
116         hci_cmd_request creq, *p_creq = &creq;
117
118         memset(p_cmdp, 0, sizeof(cmdp));
119         p_cmdp->handle = handle;
120         p_cmdp->reason = 0x13;
121         
122         memset(p_creq, 0, sizeof(creq));
123         p_creq->OCF_OGF = DISCONNECT_CMD_OP;
124         p_creq->p_cmdp = p_cmdp;
125         p_creq->cmdp_len = DISCONNECT_CP_SIZE;
126
127         if (send_cmd(p_creq) < 0) {
128                 perror("hci_disconnect_cmd wasn't sent\n");
129                 return -1;
130         }
131         return 0;
132 }
133
134 int send_hci_data(char *p_data, __u16 lenght, __u16 *p_chandle, __u16 PB_flag, __u16 B_flag)
135 {
136         hci_data_request dreq, *p_dreq = &dreq;
137
138         p_dreq->p_data = p_data;
139         p_dreq->lenght = lenght;
140         p_dreq->p_chandle = p_chandle;
141         p_dreq->PB_flag = PB_flag;
142         p_dreq->B_flag = B_flag;
143         
144         if (send_data(p_dreq) < 0) {
145                 perror("hci_accept_conn_req_cmd wasn't sent\n");
146                 return -1;
147         }
148         return 0;
149 }
150
151 /*********************************main functions****************************/
152 int send_cmd(hci_cmd_request *p_creq)
153 {
154         __u8 array[p_creq->cmdp_len + 4];
155         __u16 sw_opcode;
156         int ii;
157         
158         sw_opcode = swap_2_bytes(p_creq->OCF_OGF);
159         array[0]= HCI_COMMAND_PKT;
160         memcpy(&array[1], &sw_opcode,2);
161         array[3] = p_creq->cmdp_len;
162         if (p_creq->cmdp_len > 0) {
163                 memcpy(&array[4], p_creq->p_cmdp, p_creq->cmdp_len); // !!!!!!!!! segmentation fault
164         }
165
166         for (ii = 0; ii < sizeof(array); ii++) {
167                 printf(" %x",array[ii]);
168         }
169         printf("\n");
170
171         if (hw_bt_write(array, sizeof(array)) < 0) {
172                 perror("hw_bt_write problem\n");
173                 return -1;
174         }
175         return 0;
176 }
177
178 int send_data(hci_data_request *p_dreq)
179 {
180         int ii;
181         __u8 array[p_dreq->lenght + 4];
182         __u16 handle_flags;
183         
184         printf("old handle:%d\n", *p_dreq->p_chandle);
185         p_dreq->PB_flag = p_dreq->PB_flag << 12;
186         p_dreq->B_flag = p_dreq->B_flag << 12;
187         handle_flags = *p_dreq->p_chandle | p_dreq->PB_flag | p_dreq->B_flag;
188         printf("new hadle:%d\n", handle_flags);  
189         array[0] = HCI_ACLDATA_PKT;
190         memcpy(&array[1], &handle_flags, 2);
191         memcpy(&array[3], &p_dreq->lenght, 2);
192         memcpy(&array[5], p_dreq->p_data, p_dreq->lenght);
193         
194         printf("Outgoing data:\n");
195         for (ii = 0; ii < sizeof(array); ii++) {
196                 printf(" %x",array[ii]);
197         }
198         printf("\n");
199         
200         if (hw_bt_write(array,sizeof(array))<0) {
201                 perror("hw_bt_write problem\n");
202                 return -1;
203         }
204         return 0;
205 }
206
207 /*****************************HCI support functions*****************************/
208
209 void assemble_ocf_ogf(__u8 ocf,__u8 ogf,__u16 *p_ocf_ogf)
210 {
211         __u16 var1;
212         __u16 result;
213         
214         var1 = (ogf << 10);
215         result = ocf;
216         *p_ocf_ogf = (result | var1);
217 }
218
219 void printba(bt_address *ba)
220 {
221         printf("address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X: \n", ba->byte[0], 
222                         ba->byte[1], ba->byte[2], ba->byte[3], ba->byte[4], ba->byte[5]);
223 }
224
225 int compare_bda(bt_address *p_first, bt_address *p_second)
226 {
227         __u8 i, k = 0;
228         
229         for (i = 0; i < sizeof(bt_address); i++) {
230                 if (p_first->byte[i] == p_second->byte[i])
231                         k++;
232         }
233         
234         if (k == sizeof(bt_address)) 
235                 return 1; //all bytes are similar
236         
237         return 0; //addreses are different in one byte at least  
238 }
239
240 void fill_zero(bt_address *p_addr)
241 {
242         __u8 i;
243         
244         for (i = 0; i < sizeof(bt_address); i++) {
245                 p_addr->byte[i] = 0x00;
246         }
247 }
248
249 void swap_addrbytes(bt_address *p_addr)
250 {
251         bt_address help, *p_help = &help;
252         __u8 i;
253         
254         for (i = 0; i < sizeof(bt_address); i++) {
255                 p_help->byte[i] = p_addr->byte[5-i];
256         }
257         *p_addr = *p_help;
258 }
259
260 __u16 swap_2_bytes(__u16 twobytes)
261 {
262         __u16 first, second, result=0;
263
264         first = twobytes & 255;
265         second = twobytes & 65280;
266         result = result | (first << 8);
267         result = result | (second >> 8);
268         return result;
269 }
270
271 __u8 swap8(__u8 byte1)
272 {
273         __u8 i, mask = 0, hvar1 = 0, resvar = 0;
274         
275         for (i = 0; i < 8; i++) { 
276                 mask = 1 << i; // 1,2,4,8,16,32,64,128
277                 hvar1 = byte1 & mask;
278                 if (hvar1 > 0)
279                         resvar = resvar + (128 >> i);
280         }
281         return resvar;          
282 }
283
284 __u16 swap16(__u16 byte2)
285 {
286         __u8 i;
287         __u16 mask = 0, hvar1 = 0, resvar = 0;
288         
289         for (i = 0; i < 16; i++) {
290                 mask = 1 << i;
291                 hvar1 = byte2 & mask;
292                 if (hvar1 > 0)
293                         resvar = resvar + (32768 >> i);
294         }
295         return resvar;
296 }
297
298 void fill_add(bt_address *addr,__u8 first, __u8 sec,
299                          __u8 third, __u8 forth, __u8 fifth, __u8 sixth)
300 {       
301         addr->byte[0] = first;
302         addr->byte[1] = sec;
303         addr->byte[2] = third;
304         addr->byte[3] = forth;
305         addr->byte[4] = fifth;
306         addr->byte[5] = sixth;
307 }
308