| 581 | } |
| 582 | |
| 583 | int GetFeatureReport( unsigned char *pData, size_t nDataLen ) |
| 584 | { |
| 585 | // Make sure thread is attached to JVM/env |
| 586 | JNIEnv *env; |
| 587 | g_JVM->AttachCurrentThread( &env, NULL ); |
| 588 | pthread_setspecific( g_ThreadKey, (void*)env ); |
| 589 | |
| 590 | { |
| 591 | hid_mutex_guard cvl( &m_cvLock ); |
| 592 | if ( m_bIsWaitingForFeatureReport ) |
| 593 | { |
| 594 | LOGV( "Get feature report already ongoing... bail" ); |
| 595 | return -1; // Read already ongoing, we currently do not serialize, TODO |
| 596 | } |
| 597 | m_bIsWaitingForFeatureReport = true; |
| 598 | } |
| 599 | |
| 600 | jbyteArray pBuf = NewByteArray( env, pData, nDataLen ); |
| 601 | int nRet = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerGetFeatureReport, m_nId, pBuf ) ? 0 : -1; |
| 602 | ExceptionCheck( env, "GetFeatureReport" ); |
| 603 | env->DeleteLocalRef( pBuf ); |
| 604 | if ( nRet < 0 ) |
| 605 | { |
| 606 | LOGV( "GetFeatureReport failed" ); |
| 607 | m_bIsWaitingForFeatureReport = false; |
| 608 | return -1; |
| 609 | } |
| 610 | |
| 611 | { |
| 612 | hid_mutex_guard cvl( &m_cvLock ); |
| 613 | if ( m_bIsWaitingForFeatureReport ) |
| 614 | { |
| 615 | LOGV("=== Going to sleep" ); |
| 616 | // Wait in CV until we are no longer waiting for a feature report. |
| 617 | const int FEATURE_REPORT_TIMEOUT_SECONDS = 2; |
| 618 | struct timespec ts, endtime; |
| 619 | clock_gettime( CLOCK_REALTIME, &ts ); |
| 620 | endtime = ts; |
| 621 | endtime.tv_sec += FEATURE_REPORT_TIMEOUT_SECONDS; |
| 622 | do |
| 623 | { |
| 624 | if ( pthread_cond_timedwait( &m_cv, &m_cvLock, &endtime ) != 0 ) |
| 625 | { |
| 626 | break; |
| 627 | } |
| 628 | } |
| 629 | while ( m_bIsWaitingForFeatureReport && get_timespec_ms( ts ) < get_timespec_ms( endtime ) ); |
| 630 | |
| 631 | // We are back |
| 632 | if ( m_bIsWaitingForFeatureReport ) |
| 633 | { |
| 634 | m_nFeatureReportError = -ETIMEDOUT; |
| 635 | m_bIsWaitingForFeatureReport = false; |
| 636 | } |
| 637 | LOGV( "=== Got feature report err=%d", m_nFeatureReportError ); |
| 638 | if ( m_nFeatureReportError != 0 ) |
| 639 | { |
| 640 | return m_nFeatureReportError; |
no test coverage detected