⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hostag_receive.c

📁 bluetooth audio gateway
💻 C
字号:
#include "hostag_private.h"
#include "ag_types.h"
#include "ag.h"

#include <cm_rfcomm.h>

#include <panic.h>
#include <stdlib.h>
#include <string.h>
#include <vm.h>



/* TODO CM messages should not be passed in */



/* strnlen */
static uint16 strnlen(const uint8 *s, uint16 n)
{
    uint16 i;
    for(i = 0; i < n && s[i]; ++i) ;
    return i;
}


/*
    sendRemoteNameInd

    Remote name may be very long (up to 248 characters) so send it to
    the client using multiple packets.
*/
static void sendRemoteNameInd(const CM_INQUIRY_RESULT_IND_T *ind)
{
    int i;    
    for (i=1; i<HCI_LOCAL_NAME_BYTE_PACKET_PTRS && ind->handles[i]; i++)
    {
        uint8 *ptr = (uint8 *)VmGetPointerFromHandle(ind->handles[i]);
        uint16 len = strnlen(ptr, HCI_LOCAL_NAME_BYTES_PER_PTR);
        MAKE_PHONE_MSG_WITH_LEN(AG_REMOTE_NAME_IND, len);
        msg->ag_msg.remote_name_ind.length = len;
        memcpy(msg->ag_msg.remote_name_ind.device_name, ptr, len);
        msg->ag_msg.remote_name_ind.device_name[len] = '\0';
        msg->ag_msg.remote_name_ind.continuation_pkt_pending = 
            i+1 < HCI_LOCAL_NAME_BYTE_PACKET_PTRS && ind->handles[i+1]; /* More pending */
        hostAgPutHostMsg((void *)msg);
        free(ptr);
    }
}



/*
    handleStartCfm

    Send a message to the driver with the EAG version information This
    is really to assure the EAG driver application that the EAG is up
    and running.
*/
void handleStartCfm(void)
{
    MAKE_PHONE_MSG(AG_START_CFM);
    msg->ag_msg.start_cfm.version = EAG_VERSION;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleInquiryResultInd

    An inquiry result has been received from the Connection Manager
    Inquiry results also contain the reply from a remote name request
    so must also be able to handle long device names.
*/
void handleInquiryResultInd(const CM_INQUIRY_RESULT_IND_T *ind)
{    
    if (ind->handles[0])
    {
        uint8 *ptr = (uint8 *) VmGetPointerFromHandle(ind->handles[0]);
        uint16 len = strnlen(ptr, HCI_LOCAL_NAME_BYTES_PER_PTR);
        MAKE_PHONE_MSG_WITH_LEN(AG_INQUIRY_RESULT_IND, len);
        
        msg->ag_msg.inquiry_result_ind.dev_address.nap = ind->inq_result.bd_addr.nap;
        msg->ag_msg.inquiry_result_ind.dev_address.uap = ind->inq_result.bd_addr.uap;
        msg->ag_msg.inquiry_result_ind.dev_address.lap = ind->inq_result.bd_addr.lap;
        msg->ag_msg.inquiry_result_ind.class_of_device = ind->inq_result.dev_class;
        msg->ag_msg.inquiry_result_ind.clock_offset = ind->inq_result.clock_offset;
        msg->ag_msg.inquiry_result_ind.page_scan_rep_mode = ind->inq_result.page_scan_rep_mode;
        msg->ag_msg.inquiry_result_ind.page_scan_mode = ind->inq_result.page_scan_mode;
        msg->ag_msg.inquiry_result_ind.page_scan_period_mode = ind->inq_result.page_scan_period_mode;
        msg->ag_msg.inquiry_result_ind.length = len;
        memcpy(msg->ag_msg.inquiry_result_ind.device_name, ptr, len);
        msg->ag_msg.inquiry_result_ind.device_name[len] = '\0';
        msg->ag_msg.inquiry_result_ind.continuation_pkt_pending = (ind->handles[1] != 0);       
        hostAgPutHostMsg((void *)msg);

        /* send next pkt with remote name data */
        sendRemoteNameInd(ind);
        
        free(ptr);
    }
    else
    {
        const char *text = "Remote name not discovered";
        const uint16 len    = strlen(text);
     
        
        /* remote name not valid */
        MAKE_PHONE_MSG_WITH_LEN(AG_INQUIRY_RESULT_IND, len);
        msg->ag_msg.inquiry_result_ind.dev_address.nap = ind->inq_result.bd_addr.nap;
        msg->ag_msg.inquiry_result_ind.dev_address.uap = ind->inq_result.bd_addr.uap;
        msg->ag_msg.inquiry_result_ind.dev_address.lap = ind->inq_result.bd_addr.lap;
        msg->ag_msg.inquiry_result_ind.class_of_device = ind->inq_result.dev_class;
        msg->ag_msg.inquiry_result_ind.clock_offset = ind->inq_result.clock_offset;
        msg->ag_msg.inquiry_result_ind.page_scan_rep_mode = ind->inq_result.page_scan_rep_mode;
        msg->ag_msg.inquiry_result_ind.page_scan_mode = ind->inq_result.page_scan_mode;
        msg->ag_msg.inquiry_result_ind.page_scan_period_mode = ind->inq_result.page_scan_period_mode;
        msg->ag_msg.inquiry_result_ind.continuation_pkt_pending = 0;
        msg->ag_msg.inquiry_result_ind.length = len+1;
        memcpy(msg->ag_msg.inquiry_result_ind.device_name, text, len+1); /*lint !e669 */
        hostAgPutHostMsg((void *)msg);        
    }
}


/*
    handleInquiryCompleteCfm

    Inquiry has completed so send status to the off-chip driver
*/
void handleInquiryCompleteCfm(ag_inquiry_status_t status)
{
    MAKE_PHONE_MSG(AG_INQUIRY_COMPLETE_CFM);
    msg->ag_msg.inquiry_complete_cfm.status = status;                        
    hostAgPutHostMsg((void *)msg);
}


/*
    handlePinReq

    PIN code request received
*/
void handlePinReq(BD_ADDR_T addr)
{
    /* 
        Send a message to the off-chip app as the PIN needs to be supplied
        by the user.
    */
    MAKE_PHONE_MSG(AG_PIN_CODE_REQUEST_IND);
    msg->ag_msg.pin_code_req_ind.dev_address.nap = addr.nap;
    msg->ag_msg.pin_code_req_ind.dev_address.uap = addr.uap;
    msg->ag_msg.pin_code_req_ind.dev_address.lap = addr.lap;
    hostAgPutHostMsg((void *)msg);
}


/*
    handlePairCfm

    Pair confimation received
*/
void handlePairCfm(BD_ADDR_T addr, ag_pair_status_t status, const uint8 *link_key)
{
    /* Pairing finished so send stored link key */
    MAKE_PHONE_MSG(AG_PAIR_CFM);
    msg->ag_msg.pair_cfm.dev_address.nap = addr.nap;
    msg->ag_msg.pair_cfm.dev_address.uap = addr.uap;
    msg->ag_msg.pair_cfm.dev_address.lap = addr.lap;
    msg->ag_msg.pair_cfm.status = status;

    if (link_key)
        memcpy(msg->ag_msg.pair_cfm.link_key, link_key, AG_SIZE_LINK_KEY);
    else
        memset(msg->ag_msg.pair_cfm.link_key, 0, AG_SIZE_LINK_KEY);
    
    hostAgPutHostMsg((void *)msg);
}


/*
    handleLinkKeyReq

    Link key request received 
*/
void handleLinkKeyReq(uint16 handle)
{
    MAKE_PHONE_MSG(AG_LINK_KEY_REQUEST_IND);
    msg->ag_msg.link_key_request_ind.handle = handle; 
    hostAgPutHostMsg((void *)msg);
}


/*
    handleConnectionHandleMap

    The EAG passes the mapping between connection handle and device address 
    so that it can be passed to the external application if necessary
*/
void handleConnectionHandleMap(ag_handle_t hdl, bd_addr_t addr)
{
    /* 
        Includes both the device address and the handle assigned to it
        so the client knows which device is mapped to which handle.
    */    
    MAKE_PHONE_MSG(AG_CONNECT_REQUEST_IND);
    msg->ag_msg.connect_request_ind.handle = hdl;
    msg->ag_msg.connect_request_ind.dev_address.nap = addr.nap;
    msg->ag_msg.connect_request_ind.dev_address.uap = addr.uap;
    msg->ag_msg.connect_request_ind.dev_address.lap = addr.lap;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleScoStatusInd

    The status of the SCO connection has changed
*/
void handleScoStatusInd(ag_handle_t hdl, ag_connection_status_t status, hci_connection_handle_t sco_handle)
{
    MAKE_PHONE_MSG(AG_SCO_CONNECTION_STATUS_IND);        
    msg->ag_msg.sco_connection_status_ind.handle = hdl;
    msg->ag_msg.sco_connection_status_ind.status = status;
    msg->ag_msg.sco_connection_status_ind.sco_handle = sco_handle;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleRfcommStatusInd

    The status of the service level connection has changed
*/
void handleRfcommStatusInd(ag_handle_t hdl, ag_connection_status_t status, ag_profile_role_t role)
{
    MAKE_PHONE_MSG(AG_RFCOMM_CONNECTION_STATUS_IND);
    msg->ag_msg.rfcomm_connection_status_ind.handle = hdl;
    msg->ag_msg.rfcomm_connection_status_ind.status = status;
	msg->ag_msg.rfcomm_connection_status_ind.profile_role = role;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleVolumeChangeInd

    The volume settings have changed (could be as a result of a
    local action or a command from the remote device)
*/
void handleVolumeChangeInd(ag_handle_t hdl, uint8 gain)
{
    MAKE_PHONE_MSG(AG_VOLUME_CHANGE_IND) ;    
    msg->ag_msg.volume_change_ind.handle = hdl;
    msg->ag_msg.volume_change_ind.gain = gain;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleMicrophoneChangeInd

    The mic settings have changed (could be as a result of a
    local action or a command from the remote device)
*/
void handleMicrophoneChangeInd(ag_handle_t hdl, uint8 gain)
{
    MAKE_PHONE_MSG(AG_MIC_CHANGE_IND) ;
    msg->ag_msg.mic_change_ind.handle = hdl;
    msg->ag_msg.mic_change_ind.gain = gain;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleButtonPressInd

    Button press indication received from remote device
*/
void handleButtonPressInd(ag_handle_t hdl)
{
    MAKE_PHONE_MSG(AG_BUTTON_PRESS_IND);
    msg->ag_msg.button_press_ind.handle = hdl;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleCallAnsweredInd

    Call answered or rejected the accept_flag used to indicate which
*/
void handleCallAnsweredInd(ag_handle_t hdl, uint16 accept_flag)
{
    MAKE_PHONE_MSG(AG_CALL_ACCEPT_STATUS_IND);
    msg->ag_msg.call_accept_status_ind.handle = hdl; 
    msg->ag_msg.call_accept_status_ind.accept_or_reject = accept_flag;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleRemoteDialReq

    Dial request received from the remote dveice 
*/
void handleRemoteDialReq(ag_handle_t hdl, dial_mode_t dial_what, uint16 length, const uint8 *data)
{
    /* Alert the client */
    MAKE_PHONE_MSG_WITH_LEN(AG_DIAL_FROM_HF_REQUEST_IND, length);
    msg->ag_msg.dial_from_hf_request_ind.handle = hdl;
    msg->ag_msg.dial_from_hf_request_ind.dial_this = dial_what;
    msg->ag_msg.dial_from_hf_request_ind.length = length;

    /* The length could be zero since a last number redial does not supply data */
    if (length)
        memcpy(msg->ag_msg.dial_from_hf_request_ind.dial_data, data, length);
    else
        msg->ag_msg.dial_from_hf_request_ind.dial_data[0] = 0;

    hostAgPutHostMsg((void *)msg);            
}


/*
    handleErrorInd

    An error has occurred
*/
void handleErrorInd(ag_handle_t hdl, ag_error_code_t error_reason)
{
    MAKE_PHONE_MSG(AG_ERROR_IND);
    msg->ag_msg.error_ind.handle = hdl;
    msg->ag_msg.error_ind.reason = error_reason;
    hostAgPutHostMsg((void *)msg);
}


/*
    handleUnparsedData

    Called when RFCOMM data could not be parsed
*/
void handleUnparsedData(ag_handle_t hdl, uint16 length, const uint8 *data)
{
    MAKE_PHONE_MSG_WITH_LEN(AG_DATA_IND, length);
    msg->ag_msg.data_ind.handle = hdl;
    msg->ag_msg.data_ind.length = length;
    memcpy(msg->ag_msg.data_ind.data, data, length);
    hostAgPutHostMsg((void *)msg);
}


/*
	handleVoiceRecognitionInd

	A command enabling/ disabling voice recognition has been received and the AG
	supports it so handle it here 
*/
void handleVoiceRecognitionInd(ag_handle_t hdl, uint16 status)
{
	MAKE_PHONE_MSG(AG_VOICE_RECOG_ENABLE_IND);
	msg->ag_msg.voice_recog_enable_ind.handle = hdl;
	msg->ag_msg.voice_recog_enable_ind.enable = status;
	hostAgPutHostMsg((void *)msg);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -