📄 app_device.c
字号:
case appDevConnected:
appDevConnectedEnter(theDevice);
break;
case appDevDisconnectingLocal:
appDevDisconnectingLocalEnter(theDevice);
break;
default:
break;
}
}
appHandleDeferedAction(theDevice);
}
/*************************************************************************
NAME
appDevHandleUnexpected
DESCRIPTION
Called when a unexpected message is received, in debug mode it
will display the message id and state.
RETURNS
void
*/
static void appDevHandleUnexpected(appDeviceTaskData *theDevice, MessageId id)
{
MAIN_PRINT(("appDevHandleUnexpected, state %d, id%x\n", theDevice->state, id));
}
/*************************************************************************
NAME
appDevHandleInternalConnectReq
DESCRIPTION
Handles connect request from dongle task, stores Bluetooth address of
device and then moves into appropriate state depending on if this
is the initial connection or not.
RETURNS
void
*/
static void appDevHandleInternalConnectReq(appDeviceTaskData *theDevice, APP_DEVICE_INTERNAL_CONNECT_REQ_T *req)
{
MAIN_PRINT(("appDevHandleInternalConnectReq, nap=%d, uap=%d, lap=%ld\n", req->bd_addr.nap, req->bd_addr.uap, req->bd_addr.lap));
/* Store address */
theDevice->dev_info.bd_addr = req->bd_addr;
/* Move to connecting state */
if (req->initial)
appDevSetState(theDevice, appDevConnectingInitial);
else
appDevSetState(theDevice, appDevConnectingLocal);
}
/*************************************************************************
NAME
appDevHandleInternalConnectInd
DESCRIPTION
The function handles an incoming HID connection, sends reponses back
and sends connection indication to main task. Move to connecting
local state.
RETURNS
*/
static void appDevHandleInternalConnectInd(appDeviceTaskData *theDevice, APP_DEVICE_INTERNAL_CONNECT_IND_T *ind)
{
MAIN_PRINT(("appDevHandleInternalConnectInd\n"));
/* Accept HID connection */
HidConnectResponse(ind->hid, &theDevice->task, TRUE, &app_connection_config);
/* Move to connecting state */
appDevSetState(theDevice, appDevConnectingRemote);
}
/*************************************************************************
NAME
appDevRejectInternalConnectInd
DESCRIPTION
Rejects incoming connection.
RETURNS
void
*/
static void appDevRejectInternalConnectInd(appDeviceTaskData *theDevice, APP_DEVICE_INTERNAL_CONNECT_IND_T *ind)
{
MAIN_PRINT(("appDevRejectInternalConnectInd\n"));
/* Reject HID connection */
HidConnectResponse(ind->hid, &theDevice->task, FALSE, NULL);
}
/*************************************************************************
NAME
appDevHandleHidConnectCfm
DESCRIPTION
Handles connection confirmation, if successful stores interrupt channel
sink and moves into connected state. If unsuccessful connection then
either goes back into free state or disconnected state, depending on
if this is a new device.
RETURNS
void
*/
static void appDevHandleHidConnectCfm(appDeviceTaskData *theDevice, HID_CONNECT_CFM_T *cfm)
{
MAIN_PRINT(("appDevHandleHidConnectCfm\n"));
/* Check if connection was successful */
if (cfm->status == hid_connect_success)
{
MAIN_PRINT(("Connect successful\n"));
/* Store handle to HID connection */
theDevice->hid = cfm->hid;
/* Store HID interrupt channel sink */
theDevice->hid_sink = cfm->interrupt_sink;
/* Move to connected state */
appDevSetState(theDevice, appDevConnected);
}
else
{
MAIN_PRINT(("Connect failed\n"));
/* Check if connecting for first time */
if (appDevGetState(theDevice) == appDevConnectingInitial)
{
/* Move back to unplugged state */
appDevSetState(theDevice, appDevUnplugged);
}
else
{
/* Move back to disconnected state */
appDevSetState(theDevice, appDevDisconnected);
}
}
}
/*************************************************************************
NAME
appDevHandleHidDisconnectInd
DESCRIPTION
This function is called on reception of a HID disconnection
indication. It changes to the disconnected state.
RETURNS
void
*/
static void appDevHandleHidDisconnectInd(appDeviceTaskData *theDevice, HID_DISCONNECT_IND_T *ind)
{
MAIN_PRINT(("appDevHandleHidDisconnectInd\n"));
/* Move back to disconnected state */
appDevSetState(theDevice, appDevDisconnected);
}
/*************************************************************************
NAME
appDevHandleHidSetProtocolCfm
DESCRIPTION
This function handles the HID_SET_PROTOCOL_CFM message, if the
set protocol was successful it enters the connected (boot protocol)
state.
RETURNS
void
*/
static void appDevHandleHidSetProtocolCfm(appDeviceTaskData *theDevice, HID_SET_PROTOCOL_CFM_T *cfm)
{
MAIN_PRINT(("appDevHandleHidSetProtocolCfm, status=%d\n", cfm->status));
if (cfm->status == hid_unsupported)
{
/* Boot mode not supports, SDP record wrong! Move device to
disconnecting pending deletion state */
appDevSetState(theDevice, appDevDisconnectingLocal);
}
else if (cfm->status != hid_success)
{
/* Just disconnect, try again later */
appDevSetState(theDevice, appDevDisconnectingLocal);
}
}
/*************************************************************************
NAME
appDevHandleClSdpServiceSearchAttributeCfm
DESCRIPTION
This function handles the SDP search results.
RETURNS
void
*/
static void appDevHandleClSdpServiceSearchAttributeCfm(appDeviceTaskData *theDevice, CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM_T *cfm)
{
uint8 *ptr = cfm->attributes;
uint8 *end_ptr = &cfm->attributes[cfm->size_attributes];
MAIN_PRINT(("appDevHandleClSdpServiceSearchAttributeCfm, status=%d, size_attributes=%d\n", cfm->status, cfm->size_attributes));
switch (theDevice->sdp_state)
{
/* Expecting mandatory attributes */
case appSdpMandatory:
{
if (cfm->status == sdp_response_success)
{
appSdpResult result;
/* Get mandatory attributes */
result = appSdpHandleMandatory(theDevice, ptr, end_ptr);
if (result == appSdpOk)
{
/* Move to optional state */
theDevice->sdp_state = appSdpOptional;
/* Start SDP service and attribute search */
ConnectionSdpServiceSearchAttributeRequest(&theDevice->task, &theDevice->dev_info.bd_addr, 20,
sizeof(app_hid_service_search_pattern), app_hid_service_search_pattern,
sizeof(app_hid_attribute_list_optional), app_hid_attribute_list_optional);
}
else
{
/* Move back to unplugged state */
appDevSetState(theDevice, appDevUnplugged);
}
}
else
{
/* Move back to unplugged state */
appDevSetState(theDevice, appDevUnplugged);
}
}
break;
/* Expecting optional attributes */
case appSdpOptional:
{
if (cfm->status == sdp_response_success)
{
/* Get optional attributs */
appSdpHandleOptional(theDevice, ptr, end_ptr);
}
/* Start HID connection */
HidConnect(theDevice->theApp->hid_lib, &theDevice->task, &theDevice->dev_info.bd_addr, &app_connection_config);
}
break;
}
}
/*************************************************************************
NAME
appDevHandleUnplugReqDefer
DESCRIPTION
This function handles a unplug request when we can't handle it, so
just sets a flag to handle it later.=
RETURNS
void
*/
static void appDevHandleUnplugReqDefer(appDeviceTaskData *theDevice)
{
MAIN_PRINT(("appDevHandleUnplugReqDefer\n"));
/* Set unplug flag, we'll handle it later */
theDevice->unplug_pending = TRUE;
}
/*************************************************************************
NAME
appDevHandleUnplugReqConnected
DESCRIPTION
This function handles a unplug request when in the connected state.
RETURNS
void
*/
static void appDevHandleUnplugReqConnected(appDeviceTaskData *theDevice)
{
MAIN_PRINT(("appDevHandleUnplugReqConnected\n"));
/* Set unplug flag, we'll handle it later */
theDevice->unplug_pending = TRUE;
/* Start an unplug timer */
MessageSendLater(&theDevice->task, APP_DEVICE_INTERNAL_UNPLUG_TIMEOUT_IND, 0, D_SEC(APP_UNPLUG_TIMEOUT));
/* Send virtual unplug to host */
HidControl(theDevice->hid, hid_control_op_unplug);
}
/*************************************************************************
NAME
appDevHandleUnplugReqDisconnected
DESCRIPTION
This function handles a unplug request when in the disconnected
state.
RETURNS
void
*/
static void appDevHandleUnplugReqDisconnected(appDeviceTaskData *theDevice)
{
MAIN_PRINT(("appDevHandleUnplugReqDisconnected\n"));
/* Move to unplugged state */
appDevSetState(theDevice, appDevUnplugged);
}
/*************************************************************************
NAME
appDevHandleMoreData
DESCRIPTION
This function handles the MESSAGE_MORE_DATA messages, checks if the
data is a USB class request.
RETURNS
void
*/
static void appDevHandleMoreData(appDeviceTaskData *theDevice, MessageMoreData *msg)
{
/* Check if data from USB */
if (msg->source == theDevice->usb_source)
UsbHandleClassRequest(theDevice);
}
/*************************************************************************
NAME
devHandler
DESCRIPTION
Handles messages received for the device tasks.
RETURNS
void
*/
static void devHandler(Task task, MessageId id, Message message)
{
appDeviceTaskData *theDevice = (appDeviceTaskData *)task;
appDevState state = appDevGetState(theDevice);
switch (id)
{
case MESSAGE_MORE_DATA:
appDevHandleMoreData(theDevice, (MessageMoreData *)message);
break;
case APP_DEVICE_INTERNAL_CONNECT_REQ:
switch (state)
{
case appDevUnplugged:
appDevHandleInternalConnectReq(theDevice, (APP_DEVICE_INTERNAL_CONNECT_REQ_T *)message);
break;
default:
appDevHandleUnexpected(theDevice, id);
break;
}
break;
case APP_DEVICE_INTERNAL_CONNECT_IND:
switch (state)
{
case appDevDisconnected:
appDevHandleInternalConnectInd(theDevice, (APP_DEVICE_INTERNAL_CONNECT_IND_T *)message);
break;
default:
appDevRejectInternalConnectInd(theDevice, (APP_DEVICE_INTERNAL_CONNECT_IND_T *)message);
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -