Changeset 09bfa38f5e75d239ff955f3201095e75f13df68b

Show
Ignore:
Timestamp:
04/05/07 04:13:01 (6 years ago)
Author:
dsmith <dsmith@…>
Children:
9ef2b8aa3699c1c8aac4ba5a95d932f0b2a74fc1
Parents:
04e0f0ee34ed6e6299d325e7f38f99e66aa7ea29
git-author:
L. Donnie Smith <donnie.smith@…> (04/05/07 04:13:01)
git-committer:
dsmith <dsmith@…> (04/05/07 04:13:01)
Message:

Handle wiimote disconnect/Bluetooth error gracefully (#12)

git-svn-id: http://abstrakraft.org/cwiid/svn/trunk@65 918edb2d-ff29-0410-9de2-eb38e7f22bc7

Files:
11 modified

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r04e0f0e r09bfa38  
    33        * removed --noyywrap from lex 
    44 
     5        wiimote 
     6        * added queue_flush 
     7        * reimplemented queue_queue with queue_flush 
     8        * added wiimote_mesg_error message type 
     9        * moved RW error state to separate wiimote member 
     10        * updated wiimote_read and wiimote_write to trigger and detect rw_error 
     11        * cancel rw operations from wiimote_disconnect 
     12        * implemented process_error to handle socket read errors 
     13        * added rw_status triggers to read and write handlers 
     14 
     15        wmdemo 
     16        * made wiimote handle global 
     17        * disconnect and exit on wiimote_mesg_error 
     18 
     19        wmgui 
     20        * disconnect on wiimote_mesg_error 
     21 
     22        wminput 
     23        * exit on wiimote_mesg_error 
     24 
     252007-04-03 L. Donnie Smith <cwiid@abstrakraft.org> 
    526        wiimote 
    627        * fixed wiimote_find_wiimote seg fault 
  • wiimote/connect.c

    ra8b4be2 r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
     18 *  04/04/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
     19 *  * cancel rw operations from wiimote_disconnect 
     20 * 
    1821 *  04/01/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
    1922 *  * wiimote_connect now takes a pointer to bdaddr_t 
     
    8487        if (bacmp(bdaddr, BDADDR_ANY) == 0) { 
    8588                if (wiimote_find_wiimote(bdaddr, 2)) { 
    86                         /* TODO: wiimote functions should print their own errors */ 
    87                         wiimote_err(wiimote, "Unable to find wiimote"); 
    8889                        goto ERR_HND; 
    8990                } 
     
    144145        /* Set rw_status before interrupt thread */ 
    145146        wiimote->rw_status = RW_NONE; 
     147        wiimote->rw_error = 0; 
    146148 
    147149        /* Launch interrupt channel listener and dispatch threads */ 
     
    197199        /* Cancel and join int_thread */ 
    198200        if (pthread_cancel(wiimote->int_listen_thread)) { 
    199                 wiimote_err(wiimote, "Error canceling int_listen_thread"); 
     201                /* int could exit on it's own, so we don't care */ 
     202                /* wiimote_err(wiimote, "Error canceling int_listen_thread"); */ 
    200203        } 
    201204        else { 
     
    208211                } 
    209212        } 
    210         /* TODO: cancel RW operations if they are in progress */ 
     213 
     214        /* Cancel any RW operations in progress */ 
     215        wiimote->rw_error = 1; 
     216        if (pthread_mutex_lock(&wiimote->rw_cond_mutex)) { 
     217                wiimote_err(wiimote, "Error locking rw_cond_mutex: deadlock warning"); 
     218        } 
     219        else { 
     220                if (pthread_cond_signal(&wiimote->rw_cond)) { 
     221                        wiimote_err(wiimote, "Error signaling rw_cond: deadlock warning"); 
     222                } 
     223                if (pthread_mutex_unlock( 
     224                  &wiimote->rw_cond_mutex)) { 
     225                        wiimote_err(wiimote, "Error unlocking rw_cond_mutex"); 
     226                } 
     227        } 
     228 
    211229        /* Cancel and detach dispatch_thread */ 
    212230        /* We detach to decouple dispatch (which runs the callback) from wiimote 
     
    227245        } 
    228246 
     247        /* TODO: We have no way of telling if all in flight rw operations 
     248         * have exited yet, so for now, user must verify that all have returned 
     249         * before calling disconnect */ 
     250 
    229251        /* Destroy sync variables */ 
    230252        if (pthread_mutex_destroy(&wiimote->wiimote_mutex)) { 
  • wiimote/event.c

    r00aa494 r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
     18 *  04/04/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
     19 *  * implemented process_error to handle socket read errors 
     20 *  * added rw_status triggers to read and write handlers 
     21 * 
    1822 *  03/14/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
    1923 *  * audit error checking 
     
    102106 * placed at the end of mesg_array. */ 
    103107 
     108static int process_error(struct wiimote *, size_t); 
    104109static int process_status(struct wiimote *, const unsigned char *, 
    105110                          struct mesg_array *); 
     
    131136        do { 
    132137                /* Read packet */ 
    133                 if ((len = read(wiimote->int_socket, buf, READ_BUF_LEN)) == -1) { 
    134                         wiimote_err(wiimote, "Interrupt channel read error"); 
    135                         /* TODO: return ? */ 
     138                len = read(wiimote->int_socket, buf, READ_BUF_LEN); 
     139                if ((len == -1) || (len == 0)) { 
     140                        process_error(wiimote, len); 
     141                        /* Quit! */ 
     142                        break; 
    136143                } 
    137144                else { 
     
    162169                                case RPT_STATUS: 
    163170                                        if (process_status(wiimote, &buf[2], mesg_array)) { 
    164                                                 err = -1; 
     171                                                err = 1; 
    165172                                        } 
    166173                                        break; 
    167174                                case RPT_BTN: 
    168175                                        if (process_btn(wiimote, &buf[2], mesg_array)) { 
    169                                                 err = -1; 
     176                                                err = 1; 
    170177                                        } 
    171178                                        break; 
     
    173180                                        if (process_btn(wiimote, &buf[2], mesg_array) || 
    174181                                          process_acc(wiimote, &buf[4], mesg_array)) { 
    175                                                 err = -1; 
     182                                                err = 1; 
    176183                                        } 
    177184                                        break; 
     
    179186                                        if (process_btn(wiimote, &buf[2], mesg_array) || 
    180187                                          process_ext(wiimote, &buf[4], 8, mesg_array)) { 
    181                                                 err = -1; 
     188                                                err = 1; 
    182189                                        } 
    183190                                        break; 
     
    186193                                          process_acc(wiimote, &buf[4], mesg_array) || 
    187194                                          process_ir12(wiimote, &buf[7], mesg_array)) { 
    188                                                 err = -1; 
     195                                                err = 1; 
    189196                                        } 
    190197                                        break; 
     
    192199                                        if (process_btn(wiimote, &buf[2], mesg_array) || 
    193200                                          process_ext(wiimote, &buf[4], 19, mesg_array)) { 
    194                                                 err = -1; 
     201                                                err = 1; 
    195202                                        } 
    196203                                        break; 
     
    199206                                          process_acc(wiimote, &buf[4], mesg_array) || 
    200207                                          process_ext(wiimote, &buf[7], 16, mesg_array)) { 
    201                                                 err = -1; 
     208                                                err = 1; 
    202209                                        } 
    203210                                        break; 
     
    206213                                          process_ir10(wiimote, &buf[4], mesg_array) || 
    207214                                          process_ext(wiimote, &buf[14], 9, mesg_array)) { 
    208                                                 err = -1; 
     215                                                err = 1; 
    209216                                        } 
    210217                                        break; 
     
    214221                                          process_ir10(wiimote, &buf[7], mesg_array) || 
    215222                                          process_ext(wiimote, &buf[17], 6, mesg_array)) { 
    216                                                 err = -1; 
     223                                                err = 1; 
    217224                                        } 
    218225                                        break; 
    219226                                case RPT_EXT21: 
    220227                                        if (process_ext(wiimote, &buf[2], 21, mesg_array)) { 
    221                                                 err = -1; 
     228                                                err = 1; 
    222229                                        } 
    223230                                        break; 
     
    230237                                        if (queue_queue(wiimote->dispatch_queue, mesg_array)) { 
    231238                                                free_mesg_array(mesg_array); 
    232                                                 wiimote_err(wiimote, 
    233                                                             "error dispatching mesg array"); 
     239                                                wiimote_err(wiimote, "error dispatching mesg array"); 
    234240                                        } 
    235241                                } 
     
    254260        } while (-1); 
    255261 
    256         /* This should never execute */ 
    257262        return NULL; 
     263} 
     264 
     265static int process_error(struct wiimote *wiimote, size_t len) 
     266{ 
     267        struct mesg_array *mesg_array; 
     268        struct wiimote_error_mesg *error_mesg; 
     269        int ret = 0; 
     270 
     271        /* Error message */ 
     272        if (len == 0) { 
     273                wiimote_err(wiimote, "Disconnect"); 
     274        } 
     275        else { 
     276                wiimote_err(wiimote, "Interrupt channel read error"); 
     277        } 
     278 
     279        if ((mesg_array = malloc(sizeof *mesg_array)) == NULL) { 
     280                wiimote_err(wiimote, "Error allocating mesg array"); 
     281                ret = -1; 
     282                goto SKIP_QUEUE_MESG; 
     283        } 
     284        mesg_array->count = 1; 
     285        if ((error_mesg = malloc(sizeof *error_mesg)) == NULL) { 
     286                wiimote_err(wiimote, "Error allocating error message"); 
     287                ret = -1; 
     288                goto SKIP_QUEUE_MESG; 
     289        } 
     290        error_mesg->type = WIIMOTE_MESG_ERROR; 
     291        if (len == 0) { 
     292                error_mesg->error = WIIMOTE_ERROR_DISCONNECT; 
     293        } 
     294        else { 
     295                error_mesg->error = WIIMOTE_ERROR_COMM; 
     296        } 
     297        mesg_array->mesg[0] = error_mesg; 
     298        if (queue_flush(wiimote->dispatch_queue, (free_func_t *)free_mesg_array)) { 
     299                wiimote_err(wiimote, "error flushing dispatch queue"); 
     300                ret = -1; 
     301        } 
     302        if (queue_queue(wiimote->dispatch_queue, mesg_array)) { 
     303                free_mesg_array(mesg_array); 
     304                wiimote_err(wiimote, "error dispatching mesg array"); 
     305                ret = -1; 
     306        } 
     307 
     308SKIP_QUEUE_MESG: 
     309 
     310        /* Cancel any RW operations in progress */ 
     311        wiimote->rw_error = 1; 
     312        if (pthread_mutex_lock(&wiimote->rw_cond_mutex)) { 
     313                wiimote_err(wiimote, "Error locking rw_cond_mutex: deadlock warning"); 
     314                ret = -1; 
     315        } 
     316        else { 
     317                if (pthread_cond_signal(&wiimote->rw_cond)) { 
     318                        wiimote_err(wiimote, "Error signaling rw_cond: deadlock warning"); 
     319                        ret = -1; 
     320                } 
     321                if (pthread_mutex_unlock( 
     322                  &wiimote->rw_cond_mutex)) { 
     323                        wiimote_err(wiimote, "Error unlocking rw_cond_mutex: " 
     324                                    "deadlock warning"); 
     325                        ret = -1; 
     326                } 
     327        } 
     328 
     329        return ret; 
    258330} 
    259331 
     
    497569                  error) { 
    498570                        wiimote_err(wiimote, "Error in read data"); 
    499                         wiimote->rw_status = RW_ERROR; 
     571                        wiimote->rw_error = 1; 
     572                        wiimote->rw_status = RW_NONE; 
    500573                        ret = -1; 
    501574                } 
     
    510583                        } 
    511584                } 
    512                 if (wiimote->rw_status != RW_PENDING) { 
     585                if (wiimote->rw_error || (wiimote->rw_status != RW_PENDING)) { 
    513586                        /* Lock rw_cond_mutex, signal rw_cond, unlock 
    514587                         * rw_cond_mutex */ 
    515588                        if (pthread_mutex_lock(&wiimote->rw_cond_mutex)) { 
    516                                 wiimote_err(wiimote, "Error locking rw_cond_mutex"); 
     589                                wiimote_err(wiimote, "Error locking rw_cond_mutex: " 
     590                                            "deadlock warning"); 
     591                                wiimote->rw_error = 1; 
    517592                                ret = -1; 
    518593                        } 
     
    521596                                        wiimote_err(wiimote, "Error signaling rw_cond: " 
    522597                                                    "deadlock warning"); 
     598                                        wiimote->rw_error = 1; 
    523599                                        ret = -1; 
    524600                                } 
     
    527603                                        wiimote_err(wiimote, "Error unlocking rw_cond_mutex: " 
    528604                                                "deadlock warning"); 
     605                                        wiimote->rw_error = 1; 
    529606                                        ret = -1; 
    530607                                } 
     
    534611        else { 
    535612                wiimote_err(wiimote, "Extraneous read data received"); 
    536                 ret = 1; 
     613                ret = -1; 
    537614        } 
    538615 
     
    549626                 * write_cond_mutex */ 
    550627                if (pthread_mutex_lock(&wiimote->rw_cond_mutex)) { 
    551                         wiimote_err(wiimote, "Error locking rw_cond_mutex"); 
     628                        wiimote_err(wiimote, "Error locking rw_cond_mutex: " 
     629                                    "deadlock warning"); 
     630                        wiimote->rw_error = 1; 
    552631                        ret = -1; 
    553632                } 
     
    556635                                wiimote_err(wiimote, "Error signaling rw_cond: " 
    557636                                            "deadlock warning"); 
     637                                wiimote->rw_error = 1; 
    558638                                ret = -1; 
    559639                        } 
     
    561641                                wiimote_err(wiimote, "Error unlocking rw_cond_mutex: " 
    562642                                    "deadlock warning"); 
     643                                wiimote->rw_error = 1; 
    563644                                ret = -1; 
    564645                        } 
  • wiimote/queue.c

    r00aa494 r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
     18 *  04/04/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
     19 *  * Added queue_flush 
     20 *  * Reimplemented queue_free using queue_flush 
     21 * 
    1822 *  03/14/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
    1923 *  * audited error checking (coda and error handler sections) 
     
    5862{ 
    5963        int ret = 0; 
     64 
     65        if (queue_flush(queue, free_func)) { 
     66                ret = -1; 
     67        } 
     68        if (pthread_mutex_destroy(&queue->mutex)) { 
     69                ret = -1; 
     70        } 
     71        if (pthread_cond_destroy(&queue->cond)) { 
     72                ret = -1; 
     73        } 
     74        if (pthread_mutex_destroy(&queue->cond_mutex)) { 
     75                ret = -1; 
     76        } 
     77 
     78        free(queue); 
     79 
     80        return ret; 
     81} 
     82 
     83int queue_flush(struct queue *queue, free_func_t free_func) 
     84{ 
    6085        struct queue_node *cursor, *tmp; 
    61  
    62         if (pthread_mutex_destroy(&queue->mutex)) { 
    63                 ret = -1; 
    64         } 
    65         if (pthread_cond_destroy(&queue->cond)) { 
    66                 ret = -1; 
    67         } 
    68         if (pthread_mutex_destroy(&queue->cond_mutex)) { 
    69                 ret = -1; 
     86        int ret = 0; 
     87        int canceltype; 
     88 
     89        if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &canceltype)) { 
     90                return -1; 
     91        } 
     92 
     93        if (pthread_mutex_lock(&queue->mutex)) { 
     94                ret = -1; 
     95                goto CODA; 
    7096        } 
    7197 
     
    79105                cursor = tmp; 
    80106        } 
    81  
    82         free(queue); 
     107        queue->head = NULL; 
     108        queue->p_tail = &queue->head; 
     109 
     110        if (pthread_mutex_unlock(&queue->mutex)) { 
     111                ret = -1; 
     112                goto CODA; 
     113        } 
     114 
     115CODA: 
     116        if (pthread_setcanceltype(canceltype, &canceltype)) { 
     117                return -1; 
     118        } 
    83119 
    84120        return ret; 
  • wiimote/queue.h

    rc033b7a r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
     18 *  04/04/2007: L. Donnie Smith >cwiid@abstrakraft.org> 
     19 *  * Added queue_flush prototype 
     20 * 
    1821 *  03/03/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
    1922 *  * Initial ChangeLog 
     
    4144 
    4245struct queue *queue_new(); 
     46int queue_flush(struct queue *queue, free_func_t free_func); 
    4347int queue_free(struct queue *queue, free_func_t free_func); 
    4448int queue_queue(struct queue *queue, void *data); 
  • wiimote/rw.c

    r00aa494 r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
     18 *  04/04/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
     19 *  * updated wiimote_read and wiimote_write to trigger and detect rw_error 
     20 * 
    1821 *  03/14/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
    1922 *  * wiimote_read - changed to obey decode flag only for register read 
     
    5760        int ret = 0; 
    5861        int i; 
    59         uint8_t address_flags; 
    60  
    61         /* Lock wiimote rw access */ 
    62         if (pthread_mutex_lock(&wiimote->rw_mutex)) { 
    63                 wiimote_err(wiimote, "Error locking rw_mutex"); 
     62 
     63        /* TODO: once this code has been tested, check for rw_error before printing 
     64         * error messages */ 
     65 
     66        /* Exit immediately if rw_error */ 
     67        if (wiimote->rw_error) { 
    6468                return -1; 
    6569        } 
    6670 
    67         address_flags = flags & (WIIMOTE_RW_EEPROM | WIIMOTE_RW_REG); 
    68  
    6971        /* Compose read request packet */ 
    70         buf[0]=address_flags; 
     72        buf[0]=flags & (WIIMOTE_RW_EEPROM | WIIMOTE_RW_REG); 
    7173        buf[1]=(unsigned char)((offset>>16) & 0xFF); 
    7274        buf[2]=(unsigned char)((offset>>8) & 0xFF); 
     
    7577        buf[5]=(unsigned char)(len & 0xFF); 
    7678 
     79 
     80        /* Lock wiimote rw access */ 
     81        if (pthread_mutex_lock(&wiimote->rw_mutex)) { 
     82                wiimote_err(wiimote, "Error locking rw_mutex"); 
     83                return -1; 
     84        } 
     85 
     86        /* Check for rw_error after mutex wait */ 
     87        if (wiimote->rw_error) { 
     88                ret = -1; 
     89                goto CODA; 
     90        } 
     91 
    7792        /* Setup read info */ 
    7893        wiimote->rw_status = RW_PENDING; 
     
    85100                wiimote_err(wiimote, "Error sending read request"); 
    86101                ret = -1; 
    87         } 
     102                goto CODA; 
     103        } 
     104 
    88105        /* Lock rw_cond_mutex  */ 
    89         else if (pthread_mutex_lock(&wiimote->rw_cond_mutex)) { 
     106        if (pthread_mutex_lock(&wiimote->rw_cond_mutex)) { 
    90107                wiimote_err(wiimote, "Error locking rw_cond_mutex"); 
    91108                ret = -1; 
    92         } 
    93         else { 
    94                 /* Wait on condition, signalled by wiimote_int_listen */ 
    95                 while ((!ret) && (wiimote->rw_status == RW_PENDING)) { 
    96                         if (pthread_cond_wait(&wiimote->rw_cond, 
    97                                               &wiimote->rw_cond_mutex)) { 
    98                                 wiimote_err(wiimote, "Error waiting on rw_cond"); 
    99                                 ret = -1; 
    100                         } 
    101                 } 
    102                 /* Unlock rw_cond_mutex */ 
    103                 if (pthread_mutex_unlock(&wiimote->rw_cond_mutex)) { 
    104                         wiimote_err(wiimote, 
    105                                     "Error unlocking rw_cond_mutex: deadlock warning"); 
    106                 } 
    107  
    108                 /* Check status */ 
    109                 if (wiimote->rw_status == RW_READY) { 
    110                         ret = 0; 
    111                 } 
    112                 else { 
     109                goto CODA; 
     110        } 
     111        /* Wait on condition, signalled by int_listen */ 
     112        while (!wiimote->rw_error && !ret && (wiimote->rw_status == RW_PENDING)) { 
     113                if (pthread_cond_wait(&wiimote->rw_cond, 
     114                                      &wiimote->rw_cond_mutex)) { 
     115                        wiimote_err(wiimote, "Error waiting on rw_cond"); 
    113116                        ret = -1; 
    114                 } 
    115         } 
    116  
     117                        /* can't goto CODA from here - unlock rw_cond_mutex first */ 
     118                } 
     119        } 
     120        /* Unlock rw_cond_mutex */ 
     121        if (pthread_mutex_unlock(&wiimote->rw_cond_mutex)) { 
     122                wiimote_err(wiimote, "Error unlocking rw_cond_mutex"); 
     123                wiimote->rw_error = 1; 
     124                ret = -1; 
     125                goto CODA; 
     126        } 
     127 
     128        /* Check status */ 
     129        if (wiimote->rw_status != RW_READY) { 
     130                ret = -1; 
     131        } 
     132 
     133CODA: 
    117134        /* Clear rw_status */ 
    118135        wiimote->rw_status = RW_NONE; 
     
    121138        if (pthread_mutex_unlock(&wiimote->rw_mutex)) { 
    122139                wiimote_err(wiimote, "Error unlocking rw_mutex: deadlock warning"); 
    123         } 
    124  
    125         /* Decode only for registers */ 
    126         if ((flags & WIIMOTE_RW_DECODE) && (flags & WIIMOTE_RW_REG)) { 
     140                wiimote->rw_error = 1; 
     141        } 
     142 
     143        /* Decode (only for register reads) */ 
     144        if ((ret == 0) && (flags & WIIMOTE_RW_DECODE) && 
     145          (flags & WIIMOTE_RW_REG)) { 
    127146                for (i=0; i < len; i++) { 
    128147                        ((unsigned char *)data)[i] = DECODE(((unsigned char *)data)[i]); 
     
    141160        int ret = 0; 
    142161 
     162        /* TODO: once this code has been tested, check for rw_error before printing 
     163         * error messages */ 
     164 
     165        /* Exit immediately if rw_error */ 
     166        if (wiimote->rw_error) { 
     167                return -1; 
     168        } 
     169 
     170        /* Compose write packet header */ 
     171        buf[0]=flags; 
     172 
    143173        /* Lock wiimote rw access */ 
    144174        if (pthread_mutex_lock(&wiimote->rw_mutex)) { 
     
    147177        } 
    148178 
    149         /* Compose write packet header */ 
    150         buf[0]=flags; 
    151  
    152179        /* Send packets */ 
    153         while (!ret && (sent<len)) { 
     180        /* Check rw_error after mutex wait */ 
     181        while (!wiimote->rw_error && (sent<len)) { 
     182                wiimote->rw_status = RW_PENDING; 
     183 
     184                /* Compose write packet */ 
    154185                buf[1]=(unsigned char)(((offset+sent)>>16) & 0xFF); 
    155186                buf[2]=(unsigned char)(((offset+sent)>>8) & 0xFF); 
     
    162193                } 
    163194                memcpy(buf+5, data+sent, buf[4]); 
    164                 wiimote->rw_status = RW_PENDING; 
     195 
    165196                if (send_report(wiimote, 0, RPT_WRITE, RPT_WRITE_LEN, buf)) { 
    166197                        wiimote_err(wiimote, "Error sending write"); 
    167198                        ret = -1; 
     199                        goto CODA; 
    168200                } 
    169201                /* Lock rw_cond_mutex  */ 
     
    171203                        wiimote_err(wiimote, "Error locking rw_cond_mutex"); 
    172204                        ret = -1; 
     205                        goto CODA; 
    173206                } 
    174207                else { 
    175208                        /* Wait on condition, signalled by wiimote_int_listen */ 
    176                         while ((!ret) && (wiimote->rw_status == RW_PENDING)) { 
     209                        while (!wiimote->rw_error && !ret && 
     210                          (wiimote->rw_status == RW_PENDING)) { 
    177211                                if (pthread_cond_wait(&wiimote->rw_cond, 
    178212                                                      &wiimote->rw_cond_mutex)) { 
    179213                                        wiimote_err(wiimote, "Error waiting on rw_cond"); 
    180214                                        ret = -1; 
     215                                        /* can't goto CODA from here - 
     216                                         * unlock rw_cond_mutex first */ 
    181217                                } 
    182218                        } 
    183219                        /* Unlock rw_cond_mutex */ 
    184220                        if (pthread_mutex_unlock(&wiimote->rw_cond_mutex)) { 
    185                                 wiimote_err(wiimote, 
    186                                             "Error unlocking rw_cond_mutex: deadlock warning"); 
     221                                wiimote_err(wiimote, "Error unlocking rw_cond_mutex"); 
     222                                wiimote->rw_error = 1; 
     223                                ret = -1; 
     224                                goto CODA; 
    187225                        } 
    188226 
     227                        /* Check for error from cond_wait */ 
     228                        if (ret == -1) { 
     229                                goto CODA; 
     230                        } 
     231 
    189232                        /* Check status */ 
    190                         if (wiimote->rw_status == RW_READY) { 
    191                                 ret = 0; 
     233                        if (wiimote->rw_status != RW_READY) { 
     234                                ret = -1; 
     235                                goto CODA; 
    192236                        } 
    193                         else { 
    194                                 ret = -1; 
    195                         } 
    196237                } 
    197238                sent+=buf[4]; 
    198239        } 
    199240 
     241CODA: 
    200242        /* Clear rw_status */ 
    201243        wiimote->rw_status = RW_NONE; 
     
    204246        if (pthread_mutex_unlock(&wiimote->rw_mutex)) { 
    205247                wiimote_err(wiimote, "Error unlocking rw_mutex: deadlock warning"); 
     248                wiimote->rw_error = 1; 
    206249        } 
    207250 
  • wiimote/wiimote.h

    ra8b4be2 r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
     18 *  04/04/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
     19 *  * added wiimote_mesg_error message type 
     20 * 
    1821 *  04/01/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
    1922 *  * wiimote_connect now takes a pointer to bdaddr_t 
     
    125128        WIIMOTE_MESG_NUNCHUK, 
    126129        WIIMOTE_MESG_CLASSIC, 
     130        WIIMOTE_MESG_ERROR, 
    127131        WIIMOTE_MESG_UNKNOWN 
    128132}; 
     
    133137        WIIMOTE_EXT_CLASSIC, 
    134138        WIIMOTE_EXT_UNKNOWN 
     139}; 
     140 
     141enum wiimote_error { 
     142        WIIMOTE_ERROR_DISCONNECT, 
     143        WIIMOTE_ERROR_COMM, 
    135144}; 
    136145 
     
    186195}; 
    187196 
     197struct wiimote_error_mesg { 
     198        enum wiimote_mesg_type type; 
     199        enum wiimote_error error; 
     200}; 
     201 
    188202union wiimote_mesg { 
    189203        enum wiimote_mesg_type type; 
     
    194208        struct wiimote_nunchuk_mesg nunchuk_mesg; 
    195209        struct wiimote_classic_mesg classic_mesg; 
     210        struct wiimote_error_mesg error_mesg; 
    196211}; 
    197212 
  • wiimote/wiimote_internal.h

    rd2323a5 r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
     18 *  04/04/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
     19 *  * moved RW error state to separate member 
     20 * 
    1821 *  04/01/2007: L. Donnie Smith <cwiid@abstrakraft.org> 
    1922 *  * removed WIIMOTE_CMP_LEN macro and wiimote_findfirst prototype 
     
    132135        RW_NONE, 
    133136        RW_PENDING, 
    134         RW_READY, 
    135         RW_ERROR 
     137        RW_READY 
    136138}; 
    137139 
     
    158160        pthread_mutex_t rw_cond_mutex; 
    159161        enum rw_status rw_status; 
     162        char rw_error; 
    160163        void *read_buf; 
    161164        uint16_t read_len; 
  • wmdemo/wmdemo.c

    r2744ad3 r09bfa38  
    11#include <stdarg.h> 
    22#include <stdio.h> 
     3#include <stdlib.h> 
    34 
    45#include <wiimote.h> 
     
    3637} 
    3738 
     39/* wiimote handle */ 
     40wiimote_t *wiimote; 
     41 
    3842int main(int argc, char *argv[]) 
    3943{ 
    4044        bdaddr_t bdaddr;        /* bluetooth device address */ 
    41         wiimote_t *wiimote;     /* wiimote handle */ 
    4245        int wiimote_id;         /* wiimote id: useful for handling multiple wiimotes 
    4346                               with a single callback */ 
     
    237240                               mesg[i]->classic_mesg.l, mesg[i]->classic_mesg.r); 
    238241                        break; 
     242                case WIIMOTE_MESG_ERROR: 
     243                        if (wiimote_disconnect(wiimote)) { 
     244                                fprintf(stderr, "Error on wiimote disconnect\n"); 
     245                                exit(-1); 
     246                        } 
     247                        exit(0); 
     248                        break; 
    239249                default: 
    240250                        printf("Unknown Report"); 
  • wmgui/main.c

    rcee0ded r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
     18 *  04/04/2007 L. Donnie Smith <cwiid@abstrakraft.org> 
     19 *  * disconnect on wiimote_mesg_error 
     20 * 
    1821 *  04/03/2007 L. Donnie Smith <cwiid@abstrakraft.org> 
    1922 *  * commented custom wiimote_err (causing Xlib errors) 
     
    10591062                        wiimote_classic(&mesg_array[i]->classic_mesg); 
    10601063                        break; 
     1064                case WIIMOTE_MESG_ERROR: 
     1065                        menuDisconnect_activate(); 
     1066                        break; 
    10611067                default: 
    10621068                        break; 
  • wminput/main.c

    rb9d3519 r09bfa38  
    1616 * 
    1717 *  ChangeLog: 
    18  *  03/03/2007 L. Donnie Smith <cwiid@abstrakraft.rg> 
     18 *  04/04/2007 L. Donnie Smith <cwiid@abstrakraft.org> 
     19 *  * exit on wiimote_error 
     20 * 
     21 *  03/03/2007 L. Donnie Smith <cwiid@abstrakraft.org> 
    1922 *  * Initial ChangeLog 
    2023 *  * type audit (stdint, const, char booleans) 
     
    2730#include <pthread.h> 
    2831#include <signal.h> 
     32#include <sys/types.h> 
    2933#include <unistd.h> 
    3034 
     
    266270                        process_classic_mesg((struct wiimote_classic_mesg *) mesg[i]); 
    267271                        break; 
     272                case WIIMOTE_MESG_ERROR: 
     273                        if (kill(getpid(),SIGINT)) { 
     274                                wminput_err("error sending SIGINT"); 
     275                        } 
     276                        break; 
    268277                default: 
    269278                        break;