Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9812 was 9812, checked in by georgr, 10 years ago

Committing a few local changes, this won't work very well on non-georg boxes. @smerkli: Fix this

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