root/libcwiid/bluetooth.c

Revision 2100f14c612471084434b364501e3818c7f4144e, 4.7 kB (checked in by L. Donnie Smith <donnie.smith@…>, 3 years ago)

Various administrative updates

change email addresses
remove individual file changelogs (that's what version control is for)

  • Property mode set to 100644
Line 
1/* Copyright (C) 2007 L. Donnie Smith <donnie.smith@gatech.edu>
2 *
3 *  This program is free software; you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation; either version 2 of the License, or
6 *  (at your option) any later version.
7 *
8 *  This program is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *  GNU General Public License for more details.
12 *
13 *  You should have received a copy of the GNU General Public License
14 *  along with this program; if not, write to the Free Software
15 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16 *
17 */
18
19#include <stdlib.h>
20#include <string.h>
21#include <bluetooth/bluetooth.h>
22#include <bluetooth/hci.h>
23#include <bluetooth/hci_lib.h>
24#include "cwiid_internal.h"
25
26/* When filtering wiimotes, in order to avoid having to store the
27 * remote names before the blue_dev array is malloced (because we don't
28 * yet know how many wiimotes there are, we'll assume there are no more
29 * than dev_count, and realloc to the actual number afterwards, since
30 * reallocing to a smaller chunk should be fast. */
31#define BT_MAX_INQUIRY 256
32/* timeout in 2 second units */
33int cwiid_get_bdinfo_array(int dev_id, unsigned int timeout, int max_bdinfo,
34                           struct cwiid_bdinfo **bdinfo, uint8_t flags)
35{
36        inquiry_info *dev_list = NULL;
37        int max_inquiry;
38        int dev_count;
39        int sock = -1;
40        int bdinfo_count;
41        int i, j;
42        int err = 0;
43        int ret;
44
45        /* NULLify for the benefit of error handling */
46        *bdinfo = NULL;
47
48        /* If not given (=-1), get the first available Bluetooth interface */
49        if (dev_id == -1) {
50                if ((dev_id = hci_get_route(NULL)) == -1) {
51                        cwiid_err(NULL, "No Bluetooth interface found");
52                        return -1;
53                }
54        }
55
56        /* Get Bluetooth Device List */
57        if ((flags & BT_NO_WIIMOTE_FILTER) && (max_bdinfo != -1)) {
58                max_inquiry = max_bdinfo;
59        }
60        else {
61                max_inquiry = BT_MAX_INQUIRY;
62        }
63        if ((dev_count = hci_inquiry(dev_id, timeout, max_inquiry, NULL,
64                                     &dev_list, IREQ_CACHE_FLUSH)) == -1) {
65                cwiid_err(NULL, "Bluetooth device inquiry error");
66                err = 1;
67                goto CODA;
68        }
69
70        if (dev_count == 0) {
71                bdinfo_count = 0;
72                goto CODA;
73        }
74
75        /* Open connection to Bluetooth Interface */
76        if ((sock = hci_open_dev(dev_id)) == -1) {
77                cwiid_err(NULL, "Bluetooth interface open error");
78                err = 1;
79                goto CODA;
80        }
81
82        /* Allocate info list */
83        if (max_bdinfo == -1) {
84                max_bdinfo = dev_count;
85        }
86        if ((*bdinfo = malloc(max_bdinfo * sizeof **bdinfo)) == NULL) {
87                cwiid_err(NULL, "Memory allocation error (bdinfo array)");
88                err = 1;
89                goto CODA;
90        }
91
92        /* Copy dev_list to bdinfo */
93        for (bdinfo_count=i=0; (i < dev_count) && (bdinfo_count < max_bdinfo);
94             i++) {
95                /* Filter by class */
96                if (!(flags & BT_NO_WIIMOTE_FILTER) &&
97                  ((dev_list[i].dev_class[0] != WIIMOTE_CLASS_0) ||
98                   (dev_list[i].dev_class[1] != WIIMOTE_CLASS_1) ||
99                   (dev_list[i].dev_class[2] != WIIMOTE_CLASS_2))) {
100                        continue;
101                }
102
103                /* timeout (10000) in milliseconds */
104                if (hci_read_remote_name(sock, &dev_list[i].bdaddr, BT_NAME_LEN,
105                                         (*bdinfo)[bdinfo_count].name, 10000)) {
106                        cwiid_err(NULL, "Bluetooth name read error");
107                        err = 1;
108                        goto CODA;
109                }
110
111                /* Filter by name */
112                if (!(flags & BT_NO_WIIMOTE_FILTER) &&
113                  strncmp((*bdinfo)[bdinfo_count].name, WIIMOTE_NAME, BT_NAME_LEN) &&
114                  strncmp((*bdinfo)[bdinfo_count].name, WIIBALANCE_NAME, BT_NAME_LEN)) {
115                        continue;
116                }
117
118                /* Passed filter, add to bdinfo */
119                bacpy(&(*bdinfo)[bdinfo_count].bdaddr, &dev_list[i].bdaddr);
120                for (j=0; j<3; j++) {
121                        (*bdinfo)[bdinfo_count].btclass[j] =
122                                    dev_list[i].dev_class[j];
123                }
124                bdinfo_count++;
125        }
126
127        if (bdinfo_count == 0) {
128                free(*bdinfo);
129        }
130        else if (bdinfo_count < max_bdinfo) {
131                if ((*bdinfo = realloc(*bdinfo, bdinfo_count * sizeof **bdinfo))
132                  == NULL) {
133                        cwiid_err(NULL, "Memory reallocation error (bdinfo array)");
134                        err = 1;
135                        goto CODA;
136                }
137        }
138
139CODA:
140        if (dev_list) free(dev_list);
141        if (sock != -1) hci_close_dev(sock);
142        if (err) {
143                if (*bdinfo) free(*bdinfo);
144                ret = -1;
145        }
146        else {
147                ret = bdinfo_count;
148        }
149        return ret;
150}
151
152int cwiid_find_wiimote(bdaddr_t *bdaddr, int timeout)
153{
154        struct cwiid_bdinfo *bdinfo;
155        int bdinfo_count;
156
157        if (timeout == -1) {
158                while ((bdinfo_count = cwiid_get_bdinfo_array(-1, 2, 1, &bdinfo, 0))
159                       == 0);
160                if (bdinfo_count == -1) {
161                        return -1;
162                }
163        }
164        else {
165                bdinfo_count = cwiid_get_bdinfo_array(-1, timeout, 1, &bdinfo, 0);
166                if (bdinfo_count == -1) {
167                        return -1;
168                }
169                else if (bdinfo_count == 0) {
170                        cwiid_err(NULL, "No wiimotes found");
171                        return -1;
172                }
173        }
174
175        bacpy(bdaddr, &bdinfo[0].bdaddr);
176        free(bdinfo);
177        return 0;
178}
Note: See TracBrowser for help on using the browser.