/*****************************************************************************
NAME    
     headsetHandleIoCapabilityInd
    
DESCRIPTION
     This function is called on receipt on an CL_SM_IO_CAPABILITY_REQ_IND

RETURNS
     void 
*/
void headsetHandleIoCapabilityInd(const CL_SM_IO_CAPABILITY_REQ_IND_T* ind)
{
    /* Only send IO capabilities if we are pairable */
    if (AuthCanHeadsetPair())
    {
        cl_sm_io_capability local_io_caps = cl_sm_io_cap_display_yes_no;/*cl_sm_io_cap_no_input_no_output;*/
        AUTH_DEBUG(("auth: sending IO capability\n"));
        ConnectionSmIoCapabilityResponse(&ind->bd_addr, local_io_caps, FALSE, TRUE, FALSE, 0, 0);
    }
    else /* send a reject response */
    {
        AUTH_DEBUG(("auth: rejecting IO capability req\n"));
        ConnectionSmIoCapabilityResponse(&ind->bd_addr, cl_sm_reject_request, FALSE, FALSE, FALSE, 0, 0);
    }
}
Beispiel #2
0
void ConnectionSmIoCapabilityResponseTestExtraDefault(
        bdaddr* bd_addr,
        cl_sm_io_capability io_capability,
        bool force_mitm,
        bool bonding
        )
{
    ConnectionSmIoCapabilityResponse(
            bd_addr,
            io_capability,
            force_mitm,
            bonding,
            0,
            0,
            0
            );
}
void ConnectionSmIoCapabilityResponseTestExtra(
        uint8               type,
        bdaddr*             bd_addr,
        uint16              transport,
        cl_sm_io_capability io_capability,
        uint16              mitm,
        bool                bonding,
        uint16              key_distribution,
        uint16              oob_setting,
        uint8               size_oob_data,
        uint8*              oob_data
        )
{
    tp_bdaddr tpaddr;
    uint16 rand_r_offset = 0;
    uint8  *rand_r_ptr = NULL;

    tpaddr.transport = (TRANSPORT_T)transport;
    tpaddr.taddr.type = type;
    tpaddr.taddr.addr = *bd_addr;

    if (oob_setting & oob_data_p256)
        rand_r_offset += CL_SIZE_OOB_DATA;

    if ( 
        transport == TRANSPORT_BREDR_ACL && 
        (oob_setting & oob_data_p192)
       )
        rand_r_offset += CL_SIZE_OOB_DATA;

    if (rand_r_offset)
        rand_r_ptr = oob_data + rand_r_offset;
        
    ConnectionSmIoCapabilityResponse(
            &tpaddr,
            io_capability,
            mitm,
            bonding,
            key_distribution,
            oob_setting,
            oob_data,
            rand_r_ptr
            );
}
Beispiel #4
0
void ConnectionSmIoCapabilityResponseTestExtra(
        bdaddr* bd_addr,
        cl_sm_io_capability io_capability,
        bool force_mitm,
        bool bonding,
        uint8 size_oob_data,
        uint8* oob_data
        )
{
    ConnectionSmIoCapabilityResponse(
            bd_addr,
            io_capability,
            force_mitm,
            bonding,
            TRUE,
            oob_data,
            oob_data + CL_SIZE_OOB_DATA
            );
}
void ConnectionSmIoCapabilityResponseTestExtraDefault(
        bdaddr* bd_addr,
        cl_sm_io_capability io_capability,
        uint16 mitm,
        bool bonding
        )
{
    tp_bdaddr tpaddr;

    tpaddr.taddr.type = TYPED_BDADDR_PUBLIC;
    tpaddr.taddr.addr = *bd_addr;
    tpaddr.transport = TRANSPORT_BREDR_ACL;

    ConnectionSmIoCapabilityResponse(
            &tpaddr,
            io_capability,
            mitm,
            bonding,
            0,              /* Key distribution */
            0,              /* OOB Data setting */
            0,              /* OOB HASH_C */
            0               /* OOB RAND_R */
            );
}
Beispiel #6
0
/* Task handler function */
void BtTaskHandler(Task task, MessageId id, Message message)
{
    sppDevState state = btApp.spp_state;
    
    switch(id)
    {
    case CL_INIT_CFM:
        DEBUG(("CL_INIT_CFM\n"));
        if(((CL_INIT_CFM_T*)message)->status == success)
        {
            /* Connection Library initialisation was a success */
            /*sppDevInit();   */
            spp_init_params init;

            init.client_recipe = 0;
            init.size_service_record = 0;
	        init.service_record = 0;
	        init.no_service_record = 0;
	
            /* Initialise the spp profile lib, stating that this is device B */ 
            SppInitLazy(&btApp.task, &btApp.task, &init);
        }
        /*else
            Some reset function*/
        break;
    case CL_DM_LINK_SUPERVISION_TIMEOUT_IND:
        DEBUG(("CL_DM_LINK_SUPERVISION_TIMEOUT_IND\n"));
        break;
    case CL_DM_SNIFF_SUB_RATING_IND:
        DEBUG(("CL_DM_SNIFF_SUB_RATING_IND\n"));
        break;
    case SPP_INIT_CFM:
        DEBUG(("SPP_INIT_CFM\n"));
        switch(state)
        {
        case sppDevInitialising:
            /* Check for spp_init_success. What do we do if it failed? */
            if (((SPP_INIT_CFM_T *) message)->status == spp_init_success)
            {
                setSppState(sppDevReady);
                /* Turn off security */
                ConnectionSmRegisterIncomingService(0x0000, 0x0001, 0x0000);
                /* Write class of device */
                ConnectionWriteClassOfDevice(0x1F00);
                /* Start Inquiry mode */
                setSppState(sppDevPairable);
                /* Set devB device to inquiry scan mode, waiting for discovery */
                ConnectionWriteInquiryscanActivity(0x400, 0x200);
                ConnectionSmSetSdpSecurityIn(TRUE);
                /* Make this device discoverable (inquiry scan), and connectable (page scan) */
                ConnectionWriteScanEnable(hci_scan_enable_inq_and_page);
            }
            break;
        case sppDevReady:
        case sppDevPairable:
        case sppDevConnecting:
        case sppDevConnected:
        default:
            DEBUG(("SPP_INIT_CFM unhandled: state = %d, id = %d\n", state, id));
            break;
        }
        break;
    case SPP_CONNECT_CFM:
        {        
            SPP_CONNECT_CFM_T *cfm = (SPP_CONNECT_CFM_T *) message;
            DEBUG(("SPP_CONNECT_CFM result = %d\n", cfm->status));
            switch(state)
            {   
            case sppDevConnecting:
                /* Connect cfm, but must check status as connection may have failed */
                if (cfm->status == rfcomm_connect_success)
                {
                    /* Connection Success */
                    DEBUG(("Device connected...\n"));
                    /* Connect Uart to Rfcomm */
                    /*(void) StreamConnect(StreamUartSource(), cfm->sink);
                    (void) StreamConnect(StreamSourceFromSink(cfm->sink), StreamUartSink());*/
					/* (void) StreamConnectDispose(StreamSourceFromSink(cfm->sink)); */
                    
                    btApp.spp = cfm->spp;                    
                    btApp.sink = cfm->sink;
                    setSppState(sppDevConnected);
                    ConnectionWriteScanEnable(hci_scan_enable_off);
                }
                else
                {
                    /* Connection failed */
                    setSppState(sppDevPairable);
                    DEBUG(("Connection failed\n"));
                }
                break;
            case sppDevPairable:
                /* Connect cfm, but must check status as connection may have failed */
                if (cfm->status == rfcomm_connect_success)
                {
                    /* Device has been reset to pairable mode. Disconnect from current device */
                    SppDisconnect(cfm->spp);
                }
                break;
            case sppDevInitialising:
            case sppDevReady:
            case sppDevConnected:
            default:
                DEBUG(("SPP_CONNECT_CFM unhandled: state = %d, id = %d\n", state, id));
                break;
            }
        }
        break;
    case SPP_CONNECT_IND:
        {
            DEBUG(("SPP_CONNECT_IND\n"));        
            /*CAST_TYPED_MSG(SPP_CONNECT_IND, ind, message);*/
            switch(state)
            {   
            case sppDevPairable:
                /* Received command that a device is trying to connect. Send response. */
                SppConnectResponseLazy(((SPP_CONNECT_IND_T*)message)->spp, TRUE, &((SPP_CONNECT_IND_T*)message)->addr, 1, FRAME_SIZE);
                /*sppDevAuthoriseConnectInd(btApp,(SPP_CONNECT_IND_T*)message);*/
                setSppState(sppDevConnecting);
                break;
            case sppDevInitialising:
            case sppDevConnecting:
            case sppDevReady:
            case sppDevConnected:
            default:
                DEBUG(("SPP_CONNECT_IND unhandled: state = %d, id = %d\n", state, id));
                break;
            }
        }
        break;
    case SPP_DISCONNECT_IND:
        DEBUG(("SPP_DISCONNECT_IND\n"));
        /* Disconnect message has arrived */
        switch(state)
        {
        case sppDevConnected:
            /* Turn off security */
            ConnectionSmRegisterIncomingService(0x0000, 0x0001, 0x0000);
            /* Write class of device */
            ConnectionWriteClassOfDevice(0x1F00);
            /* Start Inquiry mode */
            setSppState(sppDevPairable);
            /* Set devB device to inquiry scan mode, waiting for discovery */
            ConnectionWriteInquiryscanActivity(0x400, 0x200);
            ConnectionSmSetSdpSecurityIn(TRUE);
            /* Make this device discoverable (inquiry scan), and connectable (page scan) */
            ConnectionWriteScanEnable(hci_scan_enable_inq_and_page);
            break;
        case sppDevInitialising:
        case sppDevPairable:
        case sppDevConnecting:
        case sppDevReady:
        default:
            DEBUG(("SPP_DISCONNECT_IND unhandled: state = %d, id = %d\n", state, id));
            break;
        }
        break;      
    case CL_DM_ACL_OPENED_IND:
        DEBUG(("CL_DM_ACL_OPENED_IND\n"));
        break;
    case CL_DM_ACL_CLOSED_IND:
        DEBUG(("CL_DM_ACL_CLOSED_IND\n"));
        break;
    case CL_SM_PIN_CODE_IND:
        DEBUG(("CL_SM_PIN_CODE_IND\n"));
        ConnectionSmPinCodeResponse(&((CL_SM_PIN_CODE_IND_T*)message)->bd_addr, 4, (uint8*)"1234");
        /*sppDevHandlePinCodeRequest((CL_SM_PIN_CODE_IND_T *) message);*/
        break;
    case CL_SM_AUTHORISE_IND:  
        DEBUG(("CL_SM_PIN_CODE_IND\n"));
        /*sppDevAuthoriseResponse((CL_SM_AUTHORISE_IND_T*) message);*/
        ConnectionSmAuthoriseResponse(&((CL_SM_AUTHORISE_IND_T*)message)->bd_addr, 
                                          ((CL_SM_AUTHORISE_IND_T*)message)->protocol_id, 
                                          ((CL_SM_AUTHORISE_IND_T*)message)->channel, 
                                          ((CL_SM_AUTHORISE_IND_T*)message)->incoming, 
                                          TRUE);
        break;
    case CL_SM_AUTHENTICATE_CFM:
        DEBUG(("CL_SM_AUTHENTICATE_CFM\n"));
        /*sppDevSetTrustLevel((CL_SM_AUTHENTICATE_CFM_T*)message);   */
        /*CAST_TYPED_MSG(CL_SM_AUTHENTICATE_CFM, cfm, message);   */  
        if(((CL_SM_AUTHENTICATE_CFM_T*)message)->status == auth_status_success)
        {
            /* Pairing success, now set the trust level*/
            ConnectionSmSetTrustLevel(&((CL_SM_AUTHENTICATE_CFM_T*)message)->bd_addr, TRUE);
        }
        else if(((CL_SM_AUTHENTICATE_CFM_T*)message)->status == auth_status_fail)
        {
             DEBUG(("Pairing failed\n"));
        }
        break;
    case CL_SM_ENCRYPTION_KEY_REFRESH_IND:
        DEBUG(("CL_SM_ENCRYPTION_KEY_REFRESH_IND\n"));
        break;
    case CL_DM_LINK_POLICY_IND:
        DEBUG(("CL_DM_LINK_POLICY_IND\n"));
        break;
    case CL_SM_IO_CAPABILITY_REQ_IND:
        DEBUG(("CL_SM_IO_CAPABILITY_REQ_IND\n"));
        ConnectionSmIoCapabilityResponse( &btApp.bd_addr, 
                                          cl_sm_io_cap_no_input_no_output,
                                          FALSE,
                                          TRUE,
                                          FALSE,
                                          0,
                                          0 );
        break;
 
    case CL_SM_REMOTE_IO_CAPABILITY_IND:
        {
            CAST_TYPED_MSG(CL_SM_REMOTE_IO_CAPABILITY_IND, csricit, message);    

            DEBUG(("CL_SM_REMOTE_IO_CAPABILITY_REQ_IND\n"));
            
            DEBUG(("\t Remote Addr: nap %04x uap %02x lap %08lx\n",
                    csricit->bd_addr.nap,
                    csricit->bd_addr.uap,
                    csricit->bd_addr.lap ));
            btApp.bd_addr = csricit->bd_addr;
        }
        break;          
    case SPP_MESSAGE_MORE_DATA:
        DEBUG(("SPP_MESSAGE_MORE_DATA\n"));
        ParseSppData(task, ((SPP_MESSAGE_MORE_DATA_T*)message)->source);
        break;
    case SPP_MESSAGE_MORE_SPACE:
        DEBUG(("SPP_MESSAGE_MORE_SPACE\n"));
        break;
	/*case BUTTON_RESET_PRESS:
		DEBUG(("Button pressed\n"));
        switch(btApp.spp_state)
        {   
        case sppDevInitialising:
            return;
            break;
        case sppDevReady:
        case sppDevPairable:
        case sppDevConnecting:
            sppDevInquire(btApp);
            break;
        case sppDevConnected:
            SppDisconnect(btApp.spp);
            break;
        }
		break;*/
    case CL_RFCOMM_CONTROL_IND:
        DEBUG(("CL_RFCOMM_CONTROL_IND\n"));
        break;        
    default:
        /* An unexpected message has arrived - must handle it */
        DEBUG(("bt app - msg type  not yet handled 0x%x\n", id));
        break;
    }
}
/****************************************************************************
NAME
    clMsgHandleLibMessage

DESCRIPTION
    Handles the CL library messages and calls the relevant function.

*/
void clMsgHandleLibMessage(MessageId id, Message message)
{
    switch(id)
    {
        case CL_INIT_CFM:
        {
            DEBUG_CL(("CL_INIT_CFM status = %u\n", ((CL_INIT_CFM_T *)message)->status));
            handleClInitCfm((CL_INIT_CFM_T *)message);    
            break;
        }    
        case CL_DM_WRITE_INQUIRY_MODE_CFM:
        {
            DEBUG_CL(("CL_DM_WRITE_INQUIRY_MODE_CFM\n"));
            /* Read the local name to put in our EIR data */
            ConnectionReadInquiryTx(&the_app->task);
            break;
        }    
        case CL_DM_READ_INQUIRY_TX_CFM:
        {
            the_app->inquiry_tx = ((CL_DM_READ_INQUIRY_TX_CFM_T*)message)->tx_power;
            ConnectionReadLocalName(&the_app->task);
            break;
        }    
        case CL_DM_LOCAL_NAME_COMPLETE:
        {
            DEBUG_CL(("CL_DM_LOCAL_NAME_COMPLETE\n"));
            /* Write EIR data and initialise the codec task */
            scanWriteEirData((CL_DM_LOCAL_NAME_COMPLETE_T*)message);
            break;
        }    
        case CL_DM_ACL_OPENED_IND:
        {
            DEBUG_CL(("CL_DM_ACL_OPENED_IND from: 0x%X 0x%X 0x%lX\n", ((CL_DM_ACL_OPENED_IND_T *)message)->bd_addr.nap, ((CL_DM_ACL_OPENED_IND_T *)message)->bd_addr.uap, ((CL_DM_ACL_OPENED_IND_T *)message)->bd_addr.lap));
            /* Ignore this message for now */
            DEBUG_CL((" - ignored\n"));
            break;
        }    
        case CL_DM_ACL_CLOSED_IND:
        {
            DEBUG_CL(("CL_DM_ACL_CLOSED_IND from: 0x%X 0x%X 0x%lX\n", ((CL_DM_ACL_CLOSED_IND_T *)message)->bd_addr.nap, ((CL_DM_ACL_CLOSED_IND_T *)message)->bd_addr.uap, ((CL_DM_ACL_CLOSED_IND_T *)message)->bd_addr.lap));
            /* Ignore this message for now */
            DEBUG_CL((" - ignored\n"));
            break;
        }
        case CL_SM_PIN_CODE_IND:
        {
            DEBUG_CL(("CL_SM_PIN_CODE_IND from: 0x%X 0x%X 0x%lX\n", (uint16)((CL_SM_PIN_CODE_IND_T *)message)->bd_addr.nap, (uint16)((CL_SM_PIN_CODE_IND_T *)message)->bd_addr.uap, (uint32)((CL_SM_PIN_CODE_IND_T *)message)->bd_addr.lap));
            handleClSmPinCodeInd((CL_SM_PIN_CODE_IND_T *)message);
            break;
        }
        case CL_SM_IO_CAPABILITY_REQ_IND:
        {
            DEBUG_CL(("CL_SM_IO_CAPABILITY_REQUEST_IND\n"));
            {
                CL_SM_IO_CAPABILITY_REQ_IND_T *prim = (CL_SM_IO_CAPABILITY_REQ_IND_T *)message;
                ConnectionSmIoCapabilityResponse(&prim->bd_addr, cl_sm_io_cap_no_input_no_output, FALSE, TRUE, FALSE, NULL, NULL);
            }
            break;
        }
        case CL_SM_USER_CONFIRMATION_REQ_IND:
        {
            DEBUG_CL(("CL_SM_USER_CONFIRMATION_REQ_IND\n"));
            /* Shouldn't get this so if we do reject it! */
            ConnectionSmUserConfirmationResponse(&((CL_SM_USER_CONFIRMATION_REQ_IND_T*)message)->bd_addr, FALSE);
            break;
        }
        case CL_SM_AUTHORISE_IND:
        {
            DEBUG_CL(("CL_SM_AUTHORISE_IND\n"));
            {    /* For now, blindly accept this request */
                CL_SM_AUTHORISE_IND_T *prim = (CL_SM_AUTHORISE_IND_T *)message;
                ConnectionSmAuthoriseResponse(&prim->bd_addr, prim->protocol_id, prim->channel, prim->incoming, TRUE);
            }    
            break;
        }
        case CL_SM_AUTHENTICATE_CFM:
        {
            DEBUG_CL(("CL_SM_AUTHENTICATE_CFM status = %u\n", ((CL_SM_AUTHENTICATE_CFM_T *)message)->status));
            if ( ((CL_SM_AUTHENTICATE_CFM_T *)message)->status == auth_status_success )
            {    /* Pin code will be stored on a successful SLC/A2DP connection */
            }
            break;
        }
        case CL_SM_SECURITY_LEVEL_CFM:
        {
            DEBUG_CL(("CL_SM_SECURITY_LEVEL_CFM success = %u\n", ((CL_SM_SECURITY_LEVEL_CFM_T *)message)->success));
            break;
        }
        case CL_DM_INQUIRE_RESULT:
        {
            DEBUG_CL(("CL_DM_INQUIRE_RESULT status = %u\n", ((CL_DM_INQUIRE_RESULT_T *)message)->status));
            handleClDmInquireResult((CL_DM_INQUIRE_RESULT_T *)message);        
            break;
        }
        case CL_SDP_OPEN_SEARCH_CFM:
        {   
            DEBUG_CL(("CL_SDP_OPEN_SEARCH_CFM status = %u\n", ((CL_SDP_OPEN_SEARCH_CFM_T *)message)->status)); 
            handleClSdpOpenSearchCfm((CL_SDP_OPEN_SEARCH_CFM_T *)message);       
            break;
        }    
        case CL_SDP_CLOSE_SEARCH_CFM:
        {
            DEBUG_CL(("CL_SDP_CLOSE_SEARCH_CFM status = %u\n", ((CL_SDP_CLOSE_SEARCH_CFM_T *)message)->status));
            handleClSdpCloseSearchCfm();      
            break;
        }    
        case CL_SDP_SERVICE_SEARCH_CFM:
        {
            DEBUG_CL(("CL_SDP_SERVICE_SEARCH_CFM status = %u\n", ((CL_SDP_SERVICE_SEARCH_CFM_T *)message)->status));
            handleClSdpServiceSearchCfm((CL_SDP_SERVICE_SEARCH_CFM_T *)message);          
            break;
        }    
        case CL_SM_SEC_MODE_CONFIG_CFM:
        {
            DEBUG_CL(("CL_SM_SEC_MODE_CONFIG_CFM\n"));
            DEBUG_CL((" - ignored\n"));
            break;
        }    
        case CL_SM_REMOTE_IO_CAPABILITY_IND:
        {
            DEBUG_CL(("CL_SM_REMOTE_IO_CAPABILITY_IND\n"));
            DEBUG_CL((" - ignored\n"));
            break;
        }
        case CL_DM_LINK_SUPERVISION_TIMEOUT_IND:
        {
            DEBUG_CL(("CL_DM_LINK_SUPERVISION_TIMEOUT_IND:\n"));
            DEBUG_CL(("    timeout:[0x%x] bdaddr:[0x%x%x%lx]\n", 
                        ((CL_DM_LINK_SUPERVISION_TIMEOUT_IND_T *)message)->timeout,
                        ((CL_DM_LINK_SUPERVISION_TIMEOUT_IND_T *)message)->bd_addr.nap,
                        ((CL_DM_LINK_SUPERVISION_TIMEOUT_IND_T *)message)->bd_addr.uap,
                        ((CL_DM_LINK_SUPERVISION_TIMEOUT_IND_T *)message)->bd_addr.lap));
            break;
        }
        case CL_DM_ROLE_IND:
        {
            DEBUG_CL(("CL_DM_ROLE_IND\n"));
            handleClRoleInd((CL_DM_ROLE_IND_T *)message);
            break;
        }
        case CL_DM_ROLE_CFM:
        {
            DEBUG_CL(("CL_DM_ROLE_CFM\n"));
            handleClRoleCfm((CL_DM_ROLE_CFM_T *)message);
            break;
        }
        case CL_DM_SNIFF_SUB_RATING_IND:
        {
            DEBUG_CL(("CL_DM_SNIFF_SUB_RATING_IND\n"));
            break;
        }
        case CL_DM_REMOTE_FEATURES_CFM:
        {
            DEBUG_CL(("CL_DM_REMOTE_FEATURES_CFM\n"));
            handleClDmRemoteFeaturesConfirm((CL_DM_REMOTE_FEATURES_CFM_T *)message);
            return;
        }

		case CL_DM_REMOTE_NAME_COMPLETE:
		{
			CL_DM_REMOTE_NAME_COMPLETE_T *name = (CL_DM_REMOTE_NAME_COMPLETE_T*)message;
			DEBUG_CL(("CL_DM_REMOTE_NAME_COMPLETE\n"));

			if(name->status == hci_success)
			{
				char *name_str = PanicUnlessMalloc(name->size_remote_name+1);
				memcpy(name_str,name->remote_name,name->size_remote_name);
				name_str[name->size_remote_name] = 0;
				UartPrintf("\r\n+RNM=%s\r\n",name_str);
				free(name_str);
			}
			else
				UartPrintf("\r\nERROR\r\n");
			
			break;
		}
		case CL_DM_RSSI_CFM:
		{
            DEBUG_CL(("CL_DM_RSSI_CFM_T %d (%d)\n",((CL_DM_RSSI_CFM_T*)message)->status,((CL_DM_RSSI_CFM_T*)message)->rssi));
			UartPrintf("\r\n+RSSI=%d\r\n",((CL_DM_RSSI_CFM_T*)message)->rssi);
            break;
		}
        default:
        {
            DEBUG_CL(("Unhandled CL message 0x%X\n", (uint16)id));    
            break;
        }
    }
}