Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/wiimote/src/external/wiicpp/wiic/io_nix.c @ 9827

Last change on this file since 9827 was 9827, checked in by smerkli, 10 years ago

Tried a few fixes to get Bluetooth to be included
properly, but no success so far. Will have to ask someone
who knows more about our CMake setup for this.

  • Property svn:executable set to *
File size: 9.1 KB
Line 
1/*
2 *    io_nix.c
3 *
4 *        This file is part of WiiC, written by:
5 *              Gabriele Randelli
6 *              Email: randelli@dis.uniroma1.it
7 *
8 *    Copyright 2010
9 *             
10 *        This file is based on Wiiuse, written By:
11 *              Michael Laforest        < para >
12 *              Email: < thepara (--AT--) g m a i l [--DOT--] com >
13 *
14 *        Copyright 2006-2007
15 *
16 *    This program is free software; you can redistribute it and/or modify
17 *    it under the terms of the GNU General Public License as published by
18 *    the Free Software Foundation; either version 3 of the License, or
19 *    (at your option) any later version.
20 *
21 *    This program is distributed in the hope that it will be useful,
22 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
23 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 *    GNU General Public License for more details.
25 *
26 *    You should have received a copy of the GNU General Public License
27 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 *
29 *        $Header$
30 */
31
32/**
33 *      @file
34 *      @brief Handles device I/O for *nix.
35 */
36
37#ifndef __APPLE__
38
39#include <stdio.h>
40#include <stdlib.h>
41#include <unistd.h>
42
43/* SANDRO HACK can't get bluetooth to work properly at the moment, will come
44 * back here and fix this very ugly inclusion as soon as I get to grips with
45 * cmake.
46 */
47#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/bluetooth.h"
48#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/hci.h"
49#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/hci_lib.h"
50#include "/home/georgr/libbluetooth-dev/libbluetooth-dev/usr/include/bluetooth/l2cap.h"
51//#include "/usr/include/bluetooth/bluetooth.h"
52//#include "/usr/include/bluetooth/hci.h"
53//#include "/usr/include/bluetooth/hci_lib.h"
54//#include "/usr/include/bluetooth/l2cap.h"
55
56#include "definitions.h"
57#include "wiic_internal.h"
58#include "io.h"
59
60/**
61 *      @brief Find a wiimote or wiimotes.
62 *
63 *      @param wm                       An array of wiimote_t structures.
64 *      @param max_wiimotes     The number of wiimote structures in \a wm.
65 *      @param timeout          The number of seconds before the search times out.
66 *
67 *      @return The number of wiimotes found.
68 *
69 *      @see wiimote_connect()
70 *
71 *      This function will only look for wiimote devices.                                               \n
72 *      When a device is found the address in the structures will be set.               \n
73 *      You can then call wiimote_connect() to connect to the found                             \n
74 *      devices.
75 */
76int wiic_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
77        int device_id;
78        int device_sock;
79        int found_devices;
80        int found_wiimotes;
81
82        /* reset all wiimote bluetooth device addresses */
83        for (found_wiimotes = 0; found_wiimotes < max_wiimotes; ++found_wiimotes)
84                wm[found_wiimotes]->bdaddr = *BDADDR_ANY;
85        found_wiimotes = 0;
86
87        /* get the id of the first bluetooth device. */
88        device_id = hci_get_route(NULL);
89        if (device_id < 0) {
90                perror("hci_get_route");
91                return 0;
92        }
93
94        /* create a socket to the device */
95        device_sock = hci_open_dev(device_id);
96        if (device_sock < 0) {
97                perror("hci_open_dev");
98                return 0;
99        }
100
101        inquiry_info scan_info_arr[128];
102        inquiry_info* scan_info = scan_info_arr;
103        memset(&scan_info_arr, 0, sizeof(scan_info_arr));
104
105        /* scan for bluetooth devices for 'timeout' seconds */
106        if(timeout)
107                found_devices = hci_inquiry(device_id, timeout, 128, NULL, &scan_info, IREQ_CACHE_FLUSH);
108        else {
109                while(!(found_devices = hci_inquiry(device_id, 5, 128, NULL, &scan_info, IREQ_CACHE_FLUSH))) ; // Unlimited inquiry
110        }
111               
112        if (found_devices < 0) {
113                perror("hci_inquiry");
114                return 0;
115        }
116
117        WIIC_INFO("Found %i bluetooth device(s).", found_devices);
118
119        int i = 0;
120
121        /* display discovered devices */
122        for (; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i) {
123                if ((scan_info[i].dev_class[0] == WM_DEV_CLASS_0) &&
124                        (scan_info[i].dev_class[1] == WM_DEV_CLASS_1) &&
125                        (scan_info[i].dev_class[2] == WM_DEV_CLASS_2))
126                {
127                        /* found a device */
128                        ba2str(&scan_info[i].bdaddr, wm[found_wiimotes]->bdaddr_str);
129
130                        WIIC_INFO("Found wiimote (%s) [id %i].", wm[found_wiimotes]->bdaddr_str, wm[found_wiimotes]->unid);
131
132                        wm[found_wiimotes]->bdaddr = scan_info[i].bdaddr;
133                        WIIMOTE_ENABLE_STATE(wm[found_wiimotes], WIIMOTE_STATE_DEV_FOUND);
134                        ++found_wiimotes;
135                }
136        }
137
138        close(device_sock);
139        return found_wiimotes;
140}
141
142
143/**
144 *      @brief Connect to a wiimote or wiimotes once an address is known.
145 *
146 *      @param wm                       An array of wiimote_t structures.
147 *      @param wiimotes         The number of wiimote structures in \a wm.
148 *  @param autoreconnect        Re-connects the device in case of unexpected disconnection.
149 *
150 *      @return The number of wiimotes that successfully connected.
151 *
152 *      @see wiic_find()
153 *      @see wiic_connect_single()
154 *      @see wiic_disconnect()
155 *
156 *      Connect to a number of wiimotes when the address is already set
157 *      in the wiimote_t structures.  These addresses are normally set
158 *      by the wiic_find() function, but can also be set manually.
159 */
160int wiic_connect(struct wiimote_t** wm, int wiimotes, int autoreconnect) 
161{
162        int connected = 0;
163        int i = 0;
164
165        for (; i < wiimotes; ++i) {
166                if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND))
167                        /* if the device address is not set, skip it */
168                        continue;
169               
170                if (wiic_connect_single(wm[i], NULL, autoreconnect)) {
171                        ++connected;
172                }
173        }
174
175        return connected;
176}
177
178/**
179 *      @brief Load Wii devices registered in the wiimotes.config file.
180 *
181 *      @param wm                       An array of wiimote_t structures.
182 *
183 *      @return The number of wiimotes successfully loaded.
184 *
185 *      @see wiic_find()
186 *  @see wiic_connect()
187 *      @see wiic_connect_single()
188 *      @see wiic_disconnect()
189 *
190 *      Up to version 0.53, it is possible to register the MAC address of your
191 *  Wii devices. This allows to automatically load them, without waiting for any
192 *  search timeout. To register a new device, go to: <HOME_DIR>/.wiic/ and
193 *  edit the file wiimotes.config, by adding the MAC address of the device
194 *  you want to register (one line per MAC address).
195 */
196int wiic_load(struct wiimote_t** wm) 
197{
198        int loaded = 0;
199        int i = 0;
200        char str[200];
201        char* str_ptr = 0;
202        char configPath[100];
203        char* tmp = 0;
204       
205        // Retrieve the HOME environment variable
206        tmp = getenv("HOME");
207        strcpy(configPath,tmp);
208        strncat(configPath,"/.wiic/wiimotes.config",22);
209
210        // Open the config file
211        FILE* fd = 0;
212        fd = fopen(configPath,"r");
213        if(!fd) 
214                return loaded;
215
216        // Read line by line
217        while(fgets(str,sizeof(str),fd) != NULL && loaded < 1) {
218                int len = strlen(str)-1;
219        if(str[len] == '\n') 
220                str[len] = 0;
221                loaded++;
222        }
223       
224        // We initialize the device structure
225        for (; i < loaded; ++i) {
226                /* found a device */
227                strncpy(wm[i]->bdaddr_str,str,18);
228                str_ptr = str;
229                str2ba(str_ptr,&(wm[i]->bdaddr));
230                WIIMOTE_ENABLE_STATE(wm[i], WIIMOTE_STATE_DEV_FOUND);
231                WIIC_INFO("Loaded Wiimote (%s) [id %i].",wm[i]->bdaddr_str,wm[i]->unid);
232        }
233
234        return loaded;
235}
236
237/**
238 *      @brief Connect to a wiimote with a known address.
239 *
240 *      @param wm               Pointer to a wiimote_t structure.
241 *      @param address  The address of the device to connect to.
242 *                                      If NULL, use the address in the struct set by wiic_find().
243 *      @param autoreconnect    Re-connect to the device in case of unexpected disconnection.
244 *
245 *      @return 1 on success, 0 on failure
246 */
247int wiic_connect_single(struct wiimote_t* wm, char* address, int autoreconnect) {
248        struct sockaddr_l2 addr;
249        memset(&addr, 0, sizeof(addr));
250
251        if (!wm || WIIMOTE_IS_CONNECTED(wm))
252                return 0;
253
254        addr.l2_family = AF_BLUETOOTH;
255
256        if (address) 
257                /* use provided address */
258                str2ba(address, &addr.l2_bdaddr);
259        else
260                /* use address of device discovered */
261                addr.l2_bdaddr = wm->bdaddr;
262
263        /*
264         *      OUTPUT CHANNEL
265         */
266        wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
267        if (wm->out_sock == -1)
268                return 0;
269
270        addr.l2_psm = htobs(WM_OUTPUT_CHANNEL);
271
272        /* connect to wiimote */
273        if (connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
274                perror("connect() output sock");
275                return 0;
276        }
277
278        /*
279         *      INPUT CHANNEL
280         */
281        wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
282        if (wm->in_sock == -1) {
283                close(wm->out_sock);
284                wm->out_sock = -1;
285                return 0;
286        }
287
288        addr.l2_psm = htobs(WM_INPUT_CHANNEL);
289
290        /* connect to wiimote */
291        if (connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
292                perror("connect() interrupt sock");
293                close(wm->out_sock);
294                wm->out_sock = -1;
295                return 0;
296        }
297       
298        /* autoreconnect flag */
299        wm->autoreconnect = autoreconnect;
300
301        WIIC_INFO("Connected to wiimote [id %i].", wm->unid);
302
303        /* do the handshake */
304        WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
305        wiic_handshake(wm, NULL, 0);
306
307        wiic_set_report_type(wm);
308
309        return 1;
310}
311
312
313/**
314 *      @brief Disconnect a wiimote.
315 *
316 *      @param wm               Pointer to a wiimote_t structure.
317 *
318 *      @see wiic_connect()
319 *
320 *      Note that this will not free the wiimote structure.
321 */
322void wiic_disconnect(struct wiimote_t* wm) {
323        if (!wm || !WIIMOTE_IS_CONNECTED(wm))
324                return;
325
326        close(wm->out_sock);
327        close(wm->in_sock);
328
329        wm->out_sock = -1;
330        wm->in_sock = -1;
331        wm->event = WIIC_NONE;
332
333        WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
334        WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
335}
336
337
338int wiic_io_read(struct wiimote_t* wm) {
339        /* not used */
340        return 0;
341}
342
343
344int wiic_io_write(struct wiimote_t* wm, byte* buf, int len) {
345        return write(wm->out_sock, buf, len);
346}
347
348
349#endif /* ifndef __APPLE__ */
Note: See TracBrowser for help on using the repository browser.