| 42 | | struct sockaddr_l2 remote_addr; |
| 43 | | char mesg_pipe_init = 0, status_pipe_init = 0, rw_pipe_init = 0, |
| 44 | | state_mutex_init = 0, rw_mutex_init = 0, rpt_mutex_init = 0, |
| 45 | | router_thread_init = 0, status_thread_init = 0; |
| 46 | | void *pthread_ret; |
| 47 | | |
| 48 | | /* Allocate wiimote */ |
| 49 | | if ((wiimote = malloc(sizeof *wiimote)) == NULL) { |
| 50 | | cwiid_err(NULL, "Memory allocation error (cwiid_wiimote_t)"); |
| 51 | | goto ERR_HND; |
| 52 | | } |
| 53 | | |
| 54 | | /* set flags */ |
| 55 | | wiimote->flags = flags; |
| 56 | | |
| 57 | | /* For error detection */ |
| 58 | | wiimote->ctl_socket = wiimote->int_socket = -1; |
| 59 | | |
| 60 | | /* Global Lock, Store and Increment wiimote_id */ |
| 61 | | if (pthread_mutex_lock(&global_mutex)) { |
| 62 | | cwiid_err(NULL, "Mutex lock error (global mutex)"); |
| 63 | | goto ERR_HND; |
| 64 | | } |
| 65 | | wiimote->id = wiimote_id++; |
| 66 | | if (pthread_mutex_unlock(&global_mutex)) { |
| 67 | | cwiid_err(wiimote, "Mutex unlock error (global mutex) - " |
| 68 | | "deadlock warning"); |
| 69 | | goto ERR_HND; |
| 70 | | } |
| 106 | | cwiid_err(wiimote, "Socket connect error (interrupt channel)"); |
| | 79 | cwiid_err(NULL, "Socket connect error (interrupt socket)"); |
| | 80 | goto ERR_HND; |
| | 81 | } |
| | 82 | |
| | 83 | if ((wiimote = cwiid_new(ctl_socket, int_socket, flags)) == NULL) { |
| | 84 | /* Raises its own error */ |
| | 85 | goto ERR_HND; |
| | 86 | } |
| | 87 | |
| | 88 | return wiimote; |
| | 89 | |
| | 90 | ERR_HND: |
| | 91 | /* Close Sockets */ |
| | 92 | if (ctl_socket != -1) { |
| | 93 | if (close(ctl_socket)) { |
| | 94 | cwiid_err(NULL, "Socket close error (control socket)"); |
| | 95 | } |
| | 96 | } |
| | 97 | if (int_socket != -1) { |
| | 98 | if (close(int_socket)) { |
| | 99 | cwiid_err(NULL, "Socket close error (interrupt socket)"); |
| | 100 | } |
| | 101 | } |
| | 102 | return NULL; |
| | 103 | } |
| | 104 | |
| | 105 | cwiid_wiimote_t *cwiid_listen(int flags) |
| | 106 | { |
| | 107 | struct sockaddr_l2 local_addr; |
| | 108 | struct sockaddr_l2 remote_addr; |
| | 109 | socklen_t socklen; |
| | 110 | int ctl_server_socket = -1, int_server_socket = -1, |
| | 111 | ctl_socket = -1, int_socket = -1; |
| | 112 | struct wiimote *wiimote = NULL; |
| | 113 | |
| | 114 | /* Connect to Wiimote */ |
| | 115 | /* Control Channel */ |
| | 116 | memset(&local_addr, 0, sizeof local_addr); |
| | 117 | local_addr.l2_family = AF_BLUETOOTH; |
| | 118 | local_addr.l2_bdaddr = *BDADDR_ANY; |
| | 119 | local_addr.l2_psm = htobs(CTL_PSM); |
| | 120 | if ((ctl_server_socket = |
| | 121 | socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1) { |
| | 122 | cwiid_err(NULL, "Socket creation error (control socket)"); |
| | 123 | goto ERR_HND; |
| | 124 | } |
| | 125 | if (bind(ctl_server_socket, (struct sockaddr *)&local_addr, |
| | 126 | sizeof local_addr)) { |
| | 127 | cwiid_err(NULL, "Socket bind error (control socket)"); |
| | 128 | goto ERR_HND; |
| | 129 | } |
| | 130 | if (listen(ctl_server_socket, 1)) { |
| | 131 | cwiid_err(NULL, "Socket listen error (control socket)"); |
| | 132 | goto ERR_HND; |
| | 133 | } |
| | 134 | |
| | 135 | /* Interrupt Channel */ |
| | 136 | local_addr.l2_psm = htobs(INT_PSM); |
| | 137 | if ((int_server_socket = |
| | 138 | socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1) { |
| | 139 | cwiid_err(NULL, "Socket creation error (interrupt socket)"); |
| | 140 | goto ERR_HND; |
| | 141 | } |
| | 142 | if (bind(int_server_socket, (struct sockaddr *)&local_addr, |
| | 143 | sizeof local_addr)) { |
| | 144 | cwiid_err(NULL, "Socket bind error (interrupt socket)"); |
| | 145 | goto ERR_HND; |
| | 146 | } |
| | 147 | if (listen(int_server_socket, 1)) { |
| | 148 | cwiid_err(NULL, "Socket listen error (interrupt socket)"); |
| | 149 | goto ERR_HND; |
| | 150 | } |
| | 151 | |
| | 152 | /* Block for Connections */ |
| | 153 | if ((ctl_socket = accept(ctl_server_socket, (struct sockaddr *)&remote_addr, &socklen)) < 0) { |
| | 154 | cwiid_err(NULL, "Socket accept error (control socket)"); |
| | 155 | goto ERR_HND; |
| | 156 | } |
| | 157 | if ((int_socket = accept(int_server_socket, (struct sockaddr *)&remote_addr, &socklen)) < 0) { |
| | 158 | cwiid_err(NULL, "Socket accept error (interrupt socket)"); |
| | 159 | goto ERR_HND; |
| | 160 | } |
| | 161 | |
| | 162 | /* Close server sockets */ |
| | 163 | if (close(ctl_server_socket)) { |
| | 164 | cwiid_err(NULL, "Socket close error (control socket)"); |
| | 165 | } |
| | 166 | if (close(int_server_socket)) { |
| | 167 | cwiid_err(NULL, "Socket close error (interrupt socket)"); |
| | 168 | } |
| | 169 | |
| | 170 | if ((wiimote = cwiid_new(ctl_socket, int_socket, flags)) == NULL) { |
| | 171 | /* Raises its own error */ |
| | 172 | goto ERR_HND; |
| | 173 | } |
| | 174 | |
| | 175 | return wiimote; |
| | 176 | |
| | 177 | ERR_HND: |
| | 178 | /* Close Sockets */ |
| | 179 | if (ctl_server_socket != -1) { |
| | 180 | if (close(ctl_server_socket)) { |
| | 181 | cwiid_err(NULL, "Socket close error (control server socket)"); |
| | 182 | } |
| | 183 | } |
| | 184 | if (int_server_socket != -1) { |
| | 185 | if (close(int_server_socket)) { |
| | 186 | cwiid_err(NULL, "Socket close error (interrupt server socket)"); |
| | 187 | } |
| | 188 | } |
| | 189 | if (ctl_socket != -1) { |
| | 190 | if (close(ctl_socket)) { |
| | 191 | cwiid_err(NULL, "Socket close error (control socket)"); |
| | 192 | } |
| | 193 | } |
| | 194 | if (int_socket != -1) { |
| | 195 | if (close(int_socket)) { |
| | 196 | cwiid_err(NULL, "Socket close error (interrupt socket)"); |
| | 197 | } |
| | 198 | } |
| | 199 | |
| | 200 | return NULL; |
| | 201 | } |
| | 202 | |
| | 203 | cwiid_wiimote_t *cwiid_new(int ctl_socket, int int_socket, int flags) |
| | 204 | { |
| | 205 | struct wiimote *wiimote = NULL; |
| | 206 | char mesg_pipe_init = 0, status_pipe_init = 0, rw_pipe_init = 0, |
| | 207 | state_mutex_init = 0, rw_mutex_init = 0, rpt_mutex_init = 0, |
| | 208 | router_thread_init = 0, status_thread_init = 0; |
| | 209 | void *pthread_ret; |
| | 210 | |
| | 211 | /* Allocate wiimote */ |
| | 212 | if ((wiimote = malloc(sizeof *wiimote)) == NULL) { |
| | 213 | cwiid_err(NULL, "Memory allocation error (cwiid_wiimote_t)"); |
| | 214 | goto ERR_HND; |
| | 215 | } |
| | 216 | |
| | 217 | /* set sockets and flags */ |
| | 218 | wiimote->ctl_socket = ctl_socket; |
| | 219 | wiimote->int_socket = int_socket; |
| | 220 | wiimote->flags = flags; |
| | 221 | |
| | 222 | /* Global Lock, Store and Increment wiimote_id */ |
| | 223 | if (pthread_mutex_lock(&global_mutex)) { |
| | 224 | cwiid_err(NULL, "Mutex lock error (global mutex)"); |
| | 225 | goto ERR_HND; |
| | 226 | } |
| | 227 | wiimote->id = wiimote_id++; |
| | 228 | if (pthread_mutex_unlock(&global_mutex)) { |
| | 229 | cwiid_err(wiimote, "Mutex unlock error (global mutex) - " |
| | 230 | "deadlock warning"); |