Example #1
0
/****************************************************************************

DESCRIPTION
    function to detect edge changes of buttons / multiple buttons. 

*/ 
static void ButtonsEdgeDetect ( const uint32 pInput , ButtonsTaskData * pButtonsTask ) 
{
    uint32 lNewInput = (uint32) (pInput & (pButtonsTask->gPerformInputEdgeCheck) ) ;
    uint32 lOldInput = (uint32) (pButtonsTask->gBOldInputState & pButtonsTask->gPerformInputEdgeCheck);
    uint32 lInput = ButtonsWhichButtonChanged( lOldInput , lNewInput ) ;
    
    B_DEBUG(("But Edge Det: Old Edge[%lx] New Edge[%lx] Button[%lx] Low2High[%lx}\n", lOldInput , lNewInput ,lInput ,(lNewInput & lInput)  )) ;
    
    /*if a button has changed*/
    if ( lInput )
    {
            /*determine which edge has been received and process accordingly*/
        if ( lNewInput & lInput )
        {  
            ButtonsButtonDetected ( pButtonsTask , lInput , B_LOW_TO_HIGH )   ;
            /* check whether device needs to be made connectable as a result of a button press
               on a multipoint device */
            if(theSink.features.GoConnectableButtonPress)
                sinkEnableMultipointConnectable();
        }
        else
        {
            ButtonsButtonDetected ( pButtonsTask , lInput , B_HIGH_TO_LOW  )   ;
        }
    }
}
Example #2
0
/****************************************************************************
DESCRIPTION
    function to detect level changes of buttons / multiple buttons, both 
    PIO and capsense 
*/ 
static void ButtonsLevelDetect ( const uint32 pInput , ButtonsTaskData * pButtonsTask ) 
{
    uint32 lNewInput = (uint32) (pInput & (pButtonsTask->gPerformInputLevelCheck)) ;
    uint32 lOldInput = (uint32) (pButtonsTask->gBOldInputState & pButtonsTask->gPerformInputLevelCheck);

    B_DEBUG(("But Lev Det|:NewInput[%lx] OldInput[%lx]\n", lNewInput, pButtonsTask->gBOldInputState )) ;
    
    if ( ButtonsWasButtonPressed(lOldInput, lNewInput )  )
    {
        /* check whether device needs to be made connectable as a result of a button press
           on a multipoint device */
        if(theSink.features.GoConnectableButtonPress)
            sinkEnableMultipointConnectable();

        /*cancel all previously timed messages*/   
        MessageCancelAll ( &pButtonsTask->task , B_INTERNAL_TIMER ) ;
        MessageCancelAll ( &pButtonsTask->task , B_REPEAT_TIMER ) ;
        
        /* send new timed messages*/
        MessageSendLater ( &pButtonsTask->task , B_INTERNAL_TIMER , 0 ,  pButtonsTask->button_config->long_press_time ) ; 
        MessageSendLater ( &pButtonsTask->task , B_REPEAT_TIMER   , 0 ,  pButtonsTask->button_config->repeat_time ) ;   
        
        /*having restrted the timers, reset the time*/
        pButtonsTask->gBTime = B_SHORT ;      
        
        if (stateManagerGetState() == deviceTestMode)
        {
            checkDUTKeyPress(lNewInput);
        }
    }
    /*button was released or was masked out, check to make sure there is an input bit change as vreg enable
      can generate an addition MSG without any input's changing state */
    else if(lOldInput!= lNewInput )              
    {   
        /*it was only a released if there was a button actually pressed last time around - 
          buttons we have masked out still end up here but no state changes are made  */       
        if ( lOldInput != 0 )
        {
             /*if we have had a double press in the required time 
                 and the button pressed was the same as this one*/
             if (  (pButtonsTask->gBTapCount ) && (lOldInput == pButtonsTask->gBMultipleState ) )
             {
                /* button has been released, increment multiple press counter */
                 pButtonsTask->gBTapCount++;
                 
                 B_DEBUG(("TapCount: [%lx][%lx][%x]\n", lOldInput , pButtonsTask->gBMultipleState , pButtonsTask->gBTapCount  )) ;

                 /* if the multiple press count is 2, set the time as a double, this will be used
                    if no further presses are detected before the multiple press timeout occurs */
                 if(pButtonsTask->gBTapCount == DOUBLE_PRESS)
                    pButtonsTask->gBTime = B_DOUBLE ;
                 /* if the multiple press count is 3, process immediately as a triple press and cancel the 
                    multiple press timer */
                 else if(pButtonsTask->gBTapCount == TRIPLE_PRESS)
                 {
                    pButtonsTask->gBTime = B_TRIPLE ;
                    /* indicate a triple press has been detected */
                    ButtonsButtonDetected ( pButtonsTask , lOldInput , B_TRIPLE  ); 
                    /* reset current state and multiple press counter */                    
                    pButtonsTask->gBMultipleState = 0x0000 ;
                    pButtonsTask->gBTapCount = 0;
                    MessageCancelAll ( &pButtonsTask->task , B_MULTIPLE_TIMER ) ;           
                 }
             }

             /*only send a message if it was a short one - long / v long /double handled elsewhere*/
             if ( (pButtonsTask->gBTime == B_SHORT ) )
             {
                 ButtonsButtonDetected ( pButtonsTask , lOldInput , B_SHORT  ); 
                 
                 /*store the double state*/
                 pButtonsTask->gBMultipleState = lOldInput ;
                 pButtonsTask->gBTapCount++;

                    /*start the double timer - only applicable to a short press*/
                 MessageSendLater ( &pButtonsTask->task , B_MULTIPLE_TIMER , 0 ,pButtonsTask->button_config->double_press_time ) ;
             }  
             else if ( (pButtonsTask->gBTime == B_LONG) )
             {
                 ButtonsButtonDetected ( pButtonsTask , lOldInput , B_LONG_RELEASE  );                  
             }
             else if ( (pButtonsTask->gBTime == B_VERY_LONG) )
             {
                 ButtonsButtonDetected ( pButtonsTask , lOldInput , B_VERY_LONG_RELEASE  ); 
             }
             else if ( (pButtonsTask->gBTime == B_VERY_VERY_LONG) )
             {
                 ButtonsButtonDetected ( pButtonsTask , lOldInput , B_VERY_VERY_LONG_RELEASE  ); 
             }
             
             if (pButtonsTask->gBTime != B_INVALID)
             {
                MessageCancelAll ( &pButtonsTask->task , B_INTERNAL_TIMER) ;
                MessageCancelAll ( &pButtonsTask->task , B_REPEAT_TIMER ) ; 
             }    
             
             /*removing this allows all releases to generate combination presses is this right?*/
             if ( !lNewInput )
             {
                 pButtonsTask->gBTime = B_INVALID ;      
             } 
         }     
    }
}
Example #3
0
/****************************************************************************
NAME    
    sinkHandleSlcDisconnectInd
    
DESCRIPTION
    Indication that the SLC has been released.

RETURNS
    void
*/
void sinkHandleSlcDisconnectInd( const HFP_SLC_DISCONNECT_IND_T *ind )
{	    
    conn_mask mask = deviceManagerProfilesConnected(&ind->bd_addr);

    SLC_DEBUG(("SLC: slc DiscInd for index %d, status = %d\n",ind->priority, ind->status)) ;     
        
    if(ind->status == hfp_disconnect_success || ind->status == hfp_disconnect_link_loss || ind->status == hfp_disconnect_abnormally)
    {
        /* store volume info */
        deviceManagerUpdateAttributes(&ind->bd_addr, sink_hfp, ind->priority, 0); 

        /* Sends the indication to the device manager to send an event out if a device has disconnected*/
        deviceManagerDeviceDisconnectedInd(&ind->bd_addr);
	
        /*if the device is off then this is disconnect as part of the power off cycle - dont re-enable connectable*/	
    	if ( stateManagerGetState() != deviceLimbo)
        {
            /* Enable A2dp link loss management if connected on remote device */
            if( theSink.a2dp_link_data && (theSink.a2dp_link_data->connected[a2dp_primary]) && BdaddrIsSame(&ind->bd_addr, &theSink.a2dp_link_data->bd_addr[a2dp_primary]) )
            {
                A2dpDeviceManageLinkloss(theSink.a2dp_link_data->device_id[a2dp_primary], TRUE);
            }
            else if( theSink.a2dp_link_data && (theSink.a2dp_link_data->connected[a2dp_secondary]) && BdaddrIsSame(&ind->bd_addr, &theSink.a2dp_link_data->bd_addr[a2dp_secondary]) )
            {
                A2dpDeviceManageLinkloss(theSink.a2dp_link_data->device_id[a2dp_secondary], TRUE);
            }

            /* Kick role checking now a device has disconnected */
            linkPolicyCheckRoles();

            /* at least one device disconnected, re-enable connectable for another 60 seconds */
            sinkEnableMultipointConnectable();
        }
    
        /*a disconnect in active call state is a call transfer*/
        if ( (stateManagerGetState() == deviceActiveCallSCO) || 
             (stateManagerGetState() == deviceActiveCallNoSCO) )
        {
		    gSlcData.gCallTransferInProgress = TRUE ;           
        }
        else
        {
		    gSlcData.gCallTransferInProgress = FALSE ;	
        }
    
        /* if not a link loss reset the last outgoing AG as AG1 will no longer exist now */        
        theSink.last_outgoing_ag = hfp_primary_link;

        /* reset the list id of the device just dropped */              
        theSink.profile_data[PROFILE_INDEX(ind->priority)].status.list_id = INVALID_LIST_ID;

        /* if device has now disconnected all profiles, mark as disconnected */
        if((ind->status != hfp_disconnect_link_loss)&&(!(mask & conn_hfp)))
            theSink.profile_data[PROFILE_INDEX(ind->priority)].status.connected = FALSE;
        
        /* If primary disconnected */
        if(ind->priority == hfp_primary_link)
        {
            /* ...and we have a secondary link it will be promoted to primary */
            if(theSink.profile_data[PROFILE_INDEX(hfp_secondary_link)].status.list_id != INVALID_LIST_ID)
            {
                /* Block copy secondary data to primary location */
                theSink.profile_data[PROFILE_INDEX(hfp_primary_link)] = theSink.profile_data[PROFILE_INDEX(hfp_secondary_link)];
                /* Secondary link no longer exists, set it to invalid */
                theSink.profile_data[PROFILE_INDEX(hfp_secondary_link)].status.list_id = INVALID_LIST_ID;
            }
        }
        /* send event slc disconnected only if the status of the indication is success or link loss indication */
        MessageSend(&theSink.task , ((ind->status == hfp_disconnect_link_loss) ? EventSysReconnectFailed : EventSysSLCDisconnected) , 0) ;
    }
    

    /*if the device is off then this is disconnect as part of the power off cycle, otherwise check
      whether device needs to be made connectable */	
	if ( stateManagerGetState() != deviceLimbo)
    {
	    /* if the device state still shows connected and there are no profiles currently
           connected then update the device state to reflect the change of connections */
	    if ((stateManagerIsConnected()) && (!deviceManagerNumConnectedDevs()))
	    {
	        stateManagerEnterConnectableState( FALSE ) ;
	    }
    }
    
}