Tizen 2.0 Release
[framework/connectivity/bluez.git] / test / lmptest.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2005-2010  Marcel Holtmann <marcel@holtmann.org>
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <getopt.h>
32 #include <sys/ioctl.h>
33 #include <sys/socket.h>
34
35 #include <bluetooth/bluetooth.h>
36 #include <bluetooth/hci.h>
37 #include <bluetooth/hci_lib.h>
38
39 #if 0
40 #define OCF_ERICSSON_SEND_LMP           0x0021
41 typedef struct {
42         uint16_t handle;
43         uint8_t  length;
44         uint8_t  data[17];
45 } __attribute__ ((packed)) ericsson_send_lmp_cp;
46 #define ERICSSON_SEND_LMP_CP_SIZE 20
47
48 static int ericsson_send_lmp(int dd, uint16_t handle, uint8_t length, uint8_t *data)
49 {
50         struct hci_request rq;
51         ericsson_send_lmp_cp cp;
52
53         memset(&cp, 0, sizeof(cp));
54         cp.handle = htobs(handle);
55         cp.length = length;
56         memcpy(cp.data, data, length);
57
58         memset(&rq, 0, sizeof(rq));
59         rq.ogf    = OGF_VENDOR_CMD;
60         rq.ocf    = OCF_ERICSSON_SEND_LMP;
61         rq.cparam = &cp;
62         rq.clen   = ERICSSON_SEND_LMP_CP_SIZE;
63         rq.rparam = NULL;
64         rq.rlen   = 0;
65
66         if (hci_send_req(dd, &rq, 1000) < 0)
67                 return -1;
68
69         return 0;
70 }
71 #endif
72
73 #define OCF_ERICSSON_WRITE_EVENTS       0x0043
74 typedef struct {
75         uint8_t mask;
76         uint8_t opcode;
77         uint8_t opcode_ext;
78 } __attribute__ ((packed)) ericsson_write_events_cp;
79 #define ERICSSON_WRITE_EVENTS_CP_SIZE 3
80
81 static int ericsson_write_events(int dd, uint8_t mask)
82 {
83         struct hci_request rq;
84         ericsson_write_events_cp cp;
85
86         memset(&cp, 0, sizeof(cp));
87         cp.mask = mask;
88         cp.opcode = 0x00;
89         cp.opcode_ext = 0x00;
90
91         memset(&rq, 0, sizeof(rq));
92         rq.ogf    = OGF_VENDOR_CMD;
93         rq.ocf    = OCF_ERICSSON_WRITE_EVENTS;
94         rq.cparam = &cp;
95         rq.clen   = ERICSSON_WRITE_EVENTS_CP_SIZE;
96         rq.rparam = NULL;
97         rq.rlen   = 0;
98
99         if (hci_send_req(dd, &rq, 1000) < 0)
100                 return -1;
101
102         return 0;
103 }
104
105 static void usage(void)
106 {
107         printf("lmptest - Utility for testing special LMP functions\n\n");
108         printf("Usage:\n"
109                 "\tlmptest [-i <dev>]\n");
110 }
111
112 static struct option main_options[] = {
113         { "device",     1, 0, 'i' },
114         { "help",       0, 0, 'h' },
115         { 0, 0, 0, 0 }
116 };
117
118 int main(int argc, char *argv[])
119 {
120         struct hci_version ver;
121         int dd, opt, dev = 0;
122
123         while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
124                 switch (opt) {
125                 case 'i':
126                         dev = hci_devid(optarg);
127                         if (dev < 0) {
128                                 perror("Invalid device");
129                                 exit(1);
130                         }
131                         break;
132
133                 case 'h':
134                 default:
135                         usage();
136                         exit(0);
137                 }
138         }
139
140         argc -= optind;
141         argv += optind;
142         optind = 0;
143
144         dd = hci_open_dev(dev);
145         if (dd < 0) {
146                 fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
147                                                 dev, strerror(errno), errno);
148                 exit(1);
149         }
150
151         if (hci_read_local_version(dd, &ver, 1000) < 0) {
152                 fprintf(stderr, "Can't read version for hci%d: %s (%d)\n",
153                                                 dev, strerror(errno), errno);
154                 hci_close_dev(dd);
155                 exit(1);
156         }
157
158         if (ver.manufacturer != 37 && ver.manufacturer != 48) {
159                 fprintf(stderr, "Can't find supported device hci%d: %s (%d)\n",
160                                                 dev, strerror(ENOSYS), ENOSYS);
161                 hci_close_dev(dd);
162                 exit(1);
163         }
164
165         if (ericsson_write_events(dd, 0x03) < 0) {
166                 fprintf(stderr, "Can't activate events for hci%d: %s (%d)\n",
167                                                 dev, strerror(errno), errno);
168                 hci_close_dev(dd);
169                 exit(1);
170         }
171
172         hci_close_dev(dd);
173
174         return 0;
175 }