Permalink
Browse files

Basic support for cwiid_listen

  • Loading branch information...
1 parent b54bd05 commit 1a6f4671cbdc7bd54db8046818012c5e3a20264b @abstrakraft committed Feb 19, 2010
Showing with 587 additions and 52 deletions.
  1. +165 −52 libcwiid/connect.c
  2. +1 −0 libcwiid/cwiid.h
  3. +4 −0 libcwiid/cwiid_internal.h
  4. +417 −0 wmdemo/wmserverdemo.c
View
@@ -33,41 +33,14 @@ static int wiimote_id = 0;
/* TODO: Turn this onto a macro on next major so version */
cwiid_wiimote_t *cwiid_open(bdaddr_t *bdaddr, int flags)
{
- return cwiid_open_timeout(bdaddr, flags, 5);
+ return cwiid_open_timeout(bdaddr, flags, DEFAULT_TIMEOUT);
}
cwiid_wiimote_t *cwiid_open_timeout(bdaddr_t *bdaddr, int flags, int timeout)
{
- struct wiimote *wiimote = NULL;
struct sockaddr_l2 remote_addr;
- char mesg_pipe_init = 0, status_pipe_init = 0, rw_pipe_init = 0,
- state_mutex_init = 0, rw_mutex_init = 0, rpt_mutex_init = 0,
- router_thread_init = 0, status_thread_init = 0;
- void *pthread_ret;
-
- /* Allocate wiimote */
- if ((wiimote = malloc(sizeof *wiimote)) == NULL) {
- cwiid_err(NULL, "Memory allocation error (cwiid_wiimote_t)");
- goto ERR_HND;
- }
-
- /* set flags */
- wiimote->flags = flags;
-
- /* For error detection */
- wiimote->ctl_socket = wiimote->int_socket = -1;
-
- /* Global Lock, Store and Increment wiimote_id */
- if (pthread_mutex_lock(&global_mutex)) {
- cwiid_err(NULL, "Mutex lock error (global mutex)");
- goto ERR_HND;
- }
- wiimote->id = wiimote_id++;
- if (pthread_mutex_unlock(&global_mutex)) {
- cwiid_err(wiimote, "Mutex unlock error (global mutex) - "
- "deadlock warning");
- goto ERR_HND;
- }
+ int ctl_socket = -1, int_socket = -1;
+ struct wiimote *wiimote = NULL;
/* If BDADDR_ANY is given, find available wiimote */
if (bacmp(bdaddr, BDADDR_ANY) == 0) {
@@ -83,27 +56,178 @@ cwiid_wiimote_t *cwiid_open_timeout(bdaddr_t *bdaddr, int flags, int timeout)
remote_addr.l2_family = AF_BLUETOOTH;
remote_addr.l2_bdaddr = *bdaddr;
remote_addr.l2_psm = htobs(CTL_PSM);
- if ((wiimote->ctl_socket =
+ if ((ctl_socket =
socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1) {
- cwiid_err(wiimote, "Socket creation error (control socket)");
+ cwiid_err(NULL, "Socket creation error (control socket)");
goto ERR_HND;
}
- if (connect(wiimote->ctl_socket, (struct sockaddr *)&remote_addr,
+ if (connect(ctl_socket, (struct sockaddr *)&remote_addr,
sizeof remote_addr)) {
- cwiid_err(wiimote, "Socket connect error (control channel)");
+ cwiid_err(NULL, "Socket connect error (control socket)");
goto ERR_HND;
}
/* Interrupt Channel */
remote_addr.l2_psm = htobs(INT_PSM);
- if ((wiimote->int_socket =
+ if ((int_socket =
socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1) {
- cwiid_err(wiimote, "Socket creation error (interrupt socket)");
+ cwiid_err(NULL, "Socket creation error (interrupt socket)");
goto ERR_HND;
}
- if (connect(wiimote->int_socket, (struct sockaddr *)&remote_addr,
+ if (connect(int_socket, (struct sockaddr *)&remote_addr,
sizeof remote_addr)) {
- cwiid_err(wiimote, "Socket connect error (interrupt channel)");
+ cwiid_err(NULL, "Socket connect error (interrupt socket)");
+ goto ERR_HND;
+ }
+
+ if ((wiimote = cwiid_new(ctl_socket, int_socket, flags)) == NULL) {
+ /* Raises its own error */
+ goto ERR_HND;
+ }
+
+ return wiimote;
+
+ERR_HND:
+ /* Close Sockets */
+ if (ctl_socket != -1) {
+ if (close(ctl_socket)) {
+ cwiid_err(NULL, "Socket close error (control socket)");
+ }
+ }
+ if (int_socket != -1) {
+ if (close(int_socket)) {
+ cwiid_err(NULL, "Socket close error (interrupt socket)");
+ }
+ }
+ return NULL;
+}
+
+cwiid_wiimote_t *cwiid_listen(int flags)
+{
+ struct sockaddr_l2 local_addr;
+ struct sockaddr_l2 remote_addr;
+ socklen_t socklen;
+ int ctl_server_socket = -1, int_server_socket = -1,
+ ctl_socket = -1, int_socket = -1;
+ struct wiimote *wiimote = NULL;
+
+ /* Connect to Wiimote */
+ /* Control Channel */
+ memset(&local_addr, 0, sizeof local_addr);
+ local_addr.l2_family = AF_BLUETOOTH;
+ local_addr.l2_bdaddr = *BDADDR_ANY;
+ local_addr.l2_psm = htobs(CTL_PSM);
+ if ((ctl_server_socket =
+ socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1) {
+ cwiid_err(NULL, "Socket creation error (control socket)");
+ goto ERR_HND;
+ }
+ if (bind(ctl_server_socket, (struct sockaddr *)&local_addr,
+ sizeof local_addr)) {
+ cwiid_err(NULL, "Socket bind error (control socket)");
+ goto ERR_HND;
+ }
+ if (listen(ctl_server_socket, 1)) {
+ cwiid_err(NULL, "Socket listen error (control socket)");
+ goto ERR_HND;
+ }
+
+ /* Interrupt Channel */
+ local_addr.l2_psm = htobs(INT_PSM);
+ if ((int_server_socket =
+ socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1) {
+ cwiid_err(NULL, "Socket creation error (interrupt socket)");
+ goto ERR_HND;
+ }
+ if (bind(int_server_socket, (struct sockaddr *)&local_addr,
+ sizeof local_addr)) {
+ cwiid_err(NULL, "Socket bind error (interrupt socket)");
+ goto ERR_HND;
+ }
+ if (listen(int_server_socket, 1)) {
+ cwiid_err(NULL, "Socket listen error (interrupt socket)");
+ goto ERR_HND;
+ }
+
+ /* Block for Connections */
+ if ((ctl_socket = accept(ctl_server_socket, (struct sockaddr *)&remote_addr, &socklen)) < 0) {
+ cwiid_err(NULL, "Socket accept error (control socket)");
+ goto ERR_HND;
+ }
+ if ((int_socket = accept(int_server_socket, (struct sockaddr *)&remote_addr, &socklen)) < 0) {
+ cwiid_err(NULL, "Socket accept error (interrupt socket)");
+ goto ERR_HND;
+ }
+
+ /* Close server sockets */
+ if (close(ctl_server_socket)) {
+ cwiid_err(NULL, "Socket close error (control socket)");
+ }
+ if (close(int_server_socket)) {
+ cwiid_err(NULL, "Socket close error (interrupt socket)");
+ }
+
+ if ((wiimote = cwiid_new(ctl_socket, int_socket, flags)) == NULL) {
+ /* Raises its own error */
+ goto ERR_HND;
+ }
+
+ return wiimote;
+
+ERR_HND:
+ /* Close Sockets */
+ if (ctl_server_socket != -1) {
+ if (close(ctl_server_socket)) {
+ cwiid_err(NULL, "Socket close error (control server socket)");
+ }
+ }
+ if (int_server_socket != -1) {
+ if (close(int_server_socket)) {
+ cwiid_err(NULL, "Socket close error (interrupt server socket)");
+ }
+ }
+ if (ctl_socket != -1) {
+ if (close(ctl_socket)) {
+ cwiid_err(NULL, "Socket close error (control socket)");
+ }
+ }
+ if (int_socket != -1) {
+ if (close(int_socket)) {
+ cwiid_err(NULL, "Socket close error (interrupt socket)");
+ }
+ }
+
+ return NULL;
+}
+
+cwiid_wiimote_t *cwiid_new(int ctl_socket, int int_socket, int flags)
+{
+ struct wiimote *wiimote = NULL;
+ char mesg_pipe_init = 0, status_pipe_init = 0, rw_pipe_init = 0,
+ state_mutex_init = 0, rw_mutex_init = 0, rpt_mutex_init = 0,
+ router_thread_init = 0, status_thread_init = 0;
+ void *pthread_ret;
+
+ /* Allocate wiimote */
+ if ((wiimote = malloc(sizeof *wiimote)) == NULL) {
+ cwiid_err(NULL, "Memory allocation error (cwiid_wiimote_t)");
+ goto ERR_HND;
+ }
+
+ /* set sockets and flags */
+ wiimote->ctl_socket = ctl_socket;
+ wiimote->int_socket = int_socket;
+ wiimote->flags = flags;
+
+ /* Global Lock, Store and Increment wiimote_id */
+ if (pthread_mutex_lock(&global_mutex)) {
+ cwiid_err(NULL, "Mutex lock error (global mutex)");
+ goto ERR_HND;
+ }
+ wiimote->id = wiimote_id++;
+ if (pthread_mutex_unlock(&global_mutex)) {
+ cwiid_err(wiimote, "Mutex unlock error (global mutex) - "
+ "deadlock warning");
goto ERR_HND;
}
@@ -156,7 +280,7 @@ cwiid_wiimote_t *cwiid_open_timeout(bdaddr_t *bdaddr, int flags, int timeout)
/* Set rw_status before starting router thread */
wiimote->rw_status = RW_IDLE;
- /* Launch interrupt channel listener and dispatch threads */
+ /* Launch interrupt socket listener and dispatch threads */
if (pthread_create(&wiimote->router_thread, NULL,
(void *(*)(void *))&router_thread, wiimote)) {
cwiid_err(wiimote, "Thread creation error (router thread)");
@@ -202,17 +326,6 @@ cwiid_wiimote_t *cwiid_open_timeout(bdaddr_t *bdaddr, int flags, int timeout)
}
}
- /* Close Sockets */
- if (wiimote->int_socket != -1) {
- if (close(wiimote->int_socket)) {
- cwiid_err(wiimote, "Socket close error (interrupt channel)");
- }
- }
- if (wiimote->ctl_socket != -1) {
- if (close(wiimote->ctl_socket)) {
- cwiid_err(wiimote, "Socket close error (control channel)");
- }
- }
/* Close Pipes */
if (mesg_pipe_init) {
if (close(wiimote->mesg_pipe[0]) || close(wiimote->mesg_pipe[1])) {
@@ -296,10 +409,10 @@ int cwiid_close(cwiid_wiimote_t *wiimote)
/* Close sockets */
if (close(wiimote->int_socket)) {
- cwiid_err(wiimote, "Socket close error (interrupt channel)");
+ cwiid_err(wiimote, "Socket close error (interrupt socket)");
}
if (close(wiimote->ctl_socket)) {
- cwiid_err(wiimote, "Socket close error (control channel)");
+ cwiid_err(wiimote, "Socket close error (control socket)");
}
/* Close Pipes */
if (close(wiimote->mesg_pipe[0]) || close(wiimote->mesg_pipe[1])) {
View
@@ -323,6 +323,7 @@ void cwiid_err_default(struct wiimote *wiimote, const char *str, va_list ap);
#define cwiid_disconnect cwiid_close
cwiid_wiimote_t *cwiid_open(bdaddr_t *bdaddr, int flags);
cwiid_wiimote_t *cwiid_open_timeout(bdaddr_t *bdaddr, int flags, int timeout);
+cwiid_wiimote_t *cwiid_listen(int flags);
int cwiid_close(cwiid_wiimote_t *wiimote);
int cwiid_get_id(cwiid_wiimote_t *wiimote);
@@ -24,6 +24,8 @@
#include <sys/types.h> /* ssize_t */
#include "cwiid.h"
+#define DEFAULT_TIMEOUT 5
+
/* Bluetooth magic numbers */
#define BT_TRANS_MASK 0xF0
#define BT_TRANS_HANDSHAKE 0x00
@@ -174,6 +176,8 @@ struct wiimote {
};
/* prototypes */
+cwiid_wiimote_t *cwiid_new(int ctl_socket, int int_socket, int flags);
+
/* thread.c */
void *router_thread(struct wiimote *wiimote);
void *status_thread(struct wiimote *wiimote);
Oops, something went wrong.

0 comments on commit 1a6f467

Please sign in to comment.