📄 hostag_receive.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 + -