📄 main.c
字号:
static void appRejectClSmAuthoriseInd(appTaskData *theApp, CL_SM_AUTHORISE_IND_T *ind)
{
MAIN_PRINT(("appRejectClSmAuthoriseInd\n"));
/* Reject connection */
ConnectionSmAuthoriseResponse(&ind->bd_addr, ind->protocol_id, ind->channel, ind->incoming, FALSE);
}
/*************************************************************************
NAME
appHandleClDmModeChangeEvent
DESCRIPTION
This function handles the CM_DM_MODE_CHANGE_EVENT message, this
message is sent when the power mode changes. This function checks if
we have entered the last sniff interval mode and starts an idle timer.
When the timer expires the HID connection will be released.
RETURNS
void
*/
static void appHandleClDmModeChangeEvent(appTaskData *theApp, CL_DM_MODE_CHANGE_EVENT_T *ev)
{
MAIN_PRINT(("appHandleClDmModeChangeEvent\n"));
/* Cancel any idle timeout message */
MessageCancelAll(&theApp->task, APP_INTERNAL_IDLE_TIMEOUT_IND);
/* Check if we have entered the last sniff interval */
if ((ev->mode == lp_sniff) && (ev->interval >= app_keyboard_power_table[APP_POWER_TABLE_ENTRIES - 1].min_interval))
{
/* Get clock offset */
ConnectionReadClockOffset(&theApp->task, theApp->interrupt_sink);
/* Send idle timeout message in 30 seconds */
MessageSendLater(&theApp->task, APP_INTERNAL_IDLE_TIMEOUT_IND, 0, D_SEC(APP_IDLE_TIMEOUT));
}
}
/*************************************************************************
NAME
appHandleClDmClockOffsetCfm
DESCRIPTION
This function handles the CM_DM_CLOCK_OFFSET_CFM message, this
message in response to a COnnectionReadClockOffset function. This
function calls ConnectionWriteCachedClockOffset to make the connection
library cache the clock offset to improve the reconnection speed.
RETURNS
void
*/
static void appHandleClDmClockOffsetCfm(appTaskData *theApp, CL_DM_CLOCK_OFFSET_CFM_T *cfm)
{
MAIN_PRINT(("appHandleClDmClockOffsetCfm, status %d, offset %d\n", cfm->status, cfm->clock_offset));
/* Check read was successful */
if (cfm->status == hci_success)
{
/* Cache clock offset */
ConnectionWriteCachedClockOffset(&theApp->host_bd_addr, cfm->clock_offset);
}
}
/*************************************************************************
NAME
appHandleHidInitConfirm
DESCRIPTION
Called when HID library has initialised, performs application
initialisation, HID transform configuration and connection
library configuration.
RETURNS
void
*/
static void appHandleHidInitConfirm(appTaskData *theApp, HID_INIT_CFM_T *cfm)
{
MAIN_PRINT(("appHandleHidInitConfirm\n"));
/* Check for HID initialised successfully */
if (cfm->status == hid_init_success)
{
/* Record HID library handle */
theApp->hid_lib = cfm->hid_lib;
/* Initialise application variables */
theApp->trusted_device_index = 0;
theApp->auth_state = appAuthIdle;
theApp->unplug_pending = FALSE;
theApp->aux_keys_state = 0;
#ifdef HW_CASIRA_UART
/* Configure HID source as UART */
PanicFalse(SourceConfigureHidSensorUART(StreamHidSource()));
/* Connect UART source to HID sink */
PanicFalse(StreamConnect(StreamUartSource(), StreamHidSink()));
/* Configure UART stream */
StreamConfigure(VM_STREAM_UART_CONFIG, VM_STREAM_UART_LATENCY);
#endif
#ifdef HW_DEV_1163A
/* Configure HID source as matrix */
PanicFalse(SourceConfigureHidSensorMatrix(StreamHidSource(), &app_hidio_config));
#endif
/* Disable idle mode and sampling */
SourceConfigure(StreamHidSource(), VM_SOURCE_HID_IDLE_MODE, 0);
SourceConfigure(StreamHidSource(), VM_SOURCE_HID_SAMPLE_RATE, 0);
/* Send Hid & HidAux messages to our task */
MessageSinkTask(StreamHidSink(), &theApp->task);
#ifdef HW_DEV_1163A
MessageSinkTask(StreamSinkFromSource(StreamHidAuxSource()), &theApp->task);
#endif
/* Move to connecting cabled state */
appSetState(theApp, appCabledConnecting);
}
else
{
/* HID failed, stop application */
Panic();
}
}
/*************************************************************************
NAME
appHandleHidConnectIndDiscoverable
DESCRIPTION
Handles incoming connection when device is discoverable. Accepts
connection and moves to connecting state.
RETURNS
void
*/
static void appHandleHidConnectIndDiscoverable(appTaskData *theApp, HID_CONNECT_IND_T *ind)
{
MAIN_PRINT(("appHandleHidConnectIndDiscoverable\n"));
/* Store HID connection instance */
theApp->hid = ind->hid;
/* Store host bluetooth address */
theApp->host_bd_addr = ind->bd_addr;
/* Accept connection */
HidConnectResponse(theApp->hid, &theApp->task, TRUE, &app_keyboard_connection_config);
/* Debug output */
MAIN_PRINT(("Connecting to host, nap=%d, uap=%d, lap=%ld\n", ind->bd_addr.nap, ind->bd_addr.uap, ind->bd_addr.lap));
/* Move to connecting discoverable state */
appSetState(theApp, appDiscoverableConnecting);
}
/*************************************************************************
NAME
appHandleHidConnectIndReject
DESCRIPTION
Rejects any incoming HID connection, used when there is already an
existing HID connection.
RETURNS
void
*/
static void appHandleHidConnectIndReject(appTaskData *app, HID_CONNECT_IND_T *ind)
{
MAIN_PRINT(("appHandleHidConnectIndReject\n"));
/* Reject connection */
HidConnectResponse(ind->hid, &app->task, FALSE, NULL);
}
/*************************************************************************
NAME
appHandleHidConnectCfm
DESCRIPTION
Handles HID connection confirmation for a new device, if successful
enters connected state and marks device as trusted otherwise just goes
back to discoverable state.
RETURNS
void
*/
static void appHandleHidConnectCfmDiscoverable(appTaskData *theApp, HID_CONNECT_CFM_T *cfm)
{
MAIN_PRINT(("appHandleHidConnectCfmDiscoverable, status=%d\n", cfm->status));
/* Check if connect was successful */
if (cfm->status == hid_connect_success)
{
/* Store HID connection instance */
theApp->hid = cfm->hid;
/* Save HID interrupt sink */
theApp->interrupt_sink = cfm->interrupt_sink;
/* Check if we are authenticated */
if (appIsAuthenticated(theApp))
{
/* Connecting successful, now set trust level */
ConnectionSmSetTrustLevel(&theApp->auth_bd_addr, TRUE);
/* Move to connected state */
appSetState(theApp, appCabledConnected);
}
else
{
/* Move to discoverable connected state */
appSetState(theApp, appDiscoverableConnected);
}
}
else
{
/* Move to discoverable state */
appSetState(theApp, appDiscoverable);
}
}
/*************************************************************************
NAME
appHandleHidConnectCfmCabled
DESCRIPTION
Handles HID connection confirmation. If confirmation was successful
enters connected state, otherwise attempts the next trusted device.
RETURNS
void
*/
static void appHandleHidConnectCfmCabled(appTaskData *theApp, HID_CONNECT_CFM_T *cfm)
{
MAIN_PRINT(("appHandleHidConnectCfmCabled, status=%d\n", cfm->status));
/* Check if connect was successful */
if (cfm->status == hid_connect_success)
{
/* Store HID connection instance */
theApp->hid = cfm->hid;
/* Save HID interrupt sink */
theApp->interrupt_sink = cfm->interrupt_sink;
/* Move to connected state */
appSetState(theApp, appCabledConnected);
}
else
{
/* Try next paired device */
theApp->trusted_device_index++;
/* Move to connecting state */
appSetState(theApp, appCabledConnecting);
}
}
/*************************************************************************
NAME
appHandleHidDisconnectInd
DESCRIPTION
Handles HID disconnection. If disconnection due to link loss,
attempts to re-establish link.
RETURNS
void
*/
static void appHandleHidDisconnectInd(appTaskData *theApp, HID_DISCONNECT_IND_T *ind)
{
MAIN_PRINT(("appHandleHidDisconnectInd, status=%d\n", ind->status));
/* Check disconnection reason */
switch (ind->status)
{
case hid_disconnect_link_loss:
{
MAIN_PRINT(("Link loss, reconnecting\n"));
/* Move to connecting local state */
appSetState(theApp, appCabledConnecting);
}
break;
case hid_disconnect_virtual_unplug:
{
MAIN_PRINT(("Virtual unplug\n"));
/* Delete all trusted devices */
ConnectionSmDeleteAllAuthDevices(APP_KEYBOARD_ATTR_PS_BASE);
/* Move to the idle state */
appSetState(theApp, appIdle);
}
break;
default:
{
/* Move to the disconnected state */
appSetState(theApp, appCabledDisconnected);
}
break;
}
}
/*************************************************************************
NAME
appHandleHidDisconnectIndDiscoverable
DESCRIPTION
Handles HID disconnection when pairing.
RETURNS
void
*/
static void appHandleHidDisconnectIndDiscoverable(appTaskData *theApp, HID_DISCONNECT_IND_T *ind)
{
MAIN_PRINT(("appHandleHidDisconnectIndDiscoverable, status=%d\n", ind->status));
/* Move to the discoverable state */
appSetState(theApp, appDiscoverable);
}
/*************************************************************************
NAME
appHandleDataDispose
DESCRIPTION
Handles data on interrupt channel passed down by firmware. This
function just free the data.
RETURNS
void
*/
static void appHandleDataDispose(appTaskData *theApp, Source source)
{
int size;
/* Loop, pulling packets from source */
while ((size = SourceBoundary(source)) != 0)
{
/* Discard the packet */
SourceDrop(source, size);
}
}
/*************************************************************************
NAME
app_handler
DESCRIPTION
Message handler for all messages in this application.
RETURNS
void
*/
static void app_handler(Task task, MessageId id, Message message)
{
appTaskData *theApp = (appTaskData *)task;
app_state state = appGetState(theApp);
switch(id)
{
/* Connection Library Messages */
case CL_INIT_CFM:
{
switch (state)
{
case appInitialising:
appHandleClInitConfirm(theApp, (CL_INIT_CFM_T *)message);
break;
default:
appHandleUnexpected(theApp, id);
break;
}
}
break;
case CL_SM_GET_INDEXED_ATTRIBUTE_CFM:
{
switch (state)
{
case appCabledConnecting:
appHandleClSmGetIndexedAttributeConfirm(theApp, (CL_SM_GET_INDEXED_ATTRIBUTE_CFM_T *)message);
break;
default:
appHandleUnexpected(theApp, id);
break;
}
}
break;
case CL_SM_PIN_CODE_IND:
{
switch (state)
{
case appDiscoverable:
case appDiscoverableConnecting:
case appDiscoverableConnected:
appHandleClSmPinCodeIndication(theApp, (CL_SM_PIN_CODE_IND_T *)message);
break;
default:
appRejectClSmPinCodeIndication(theApp, (CL_SM_PIN_CODE_IND_T *)message);
break;
}
}
break;
case CL_SM_AUTHENTICATE_CFM:
{
switch (state)
{
case appDiscoverable:
case appDiscoverableConnecting:
case appCabledConnecting:
case appCabledConnected:
appHandleClSmAuthenticateConfirm(theApp, (CL_SM_AUTHENTICATE_CFM_T *)message);
break;
case appDiscoverableConnected:
appHandleClSmAuthenticateConfirmDiscoverableConnected(theApp, (CL_SM_AUTHENTICATE_CFM_T *)message);
break;
default:
appHandleUnexpected(theApp, id);
break;
}
}
break;
case CL_SM_AUTHORISE_IND:
{
switch (state)
{
case appDiscoverable:
case appDiscoverableConnecting:
appHandleClSmAuthoriseInd(theApp, (CL_SM_AUTHORISE_IND_T *)message);
break;
default:
appRejectClSmAuthoriseInd(theApp, (CL_SM_AUTHORISE_IND_T *)message);
break;
}
}
break;
case CL_DM_CLOCK_OFFSET_CFM:
{
switch (state)
{
case appCabledConnected:
appHandleClDmClockOffsetCfm(theApp, (CL_DM_CLOCK_OFFSET_CFM_T *)message);
break;
default:
break;
}
}
break;
case CL_DM_MODE_CHANGE_EVENT:
{
switch (state)
{
case appCabledConnected:
appHandleClDmModeChangeEvent(theApp, (CL_DM_MODE_CHANGE_EVENT_T *)message);
break;
default:
break;
}
}
break;
case CL_SM_SECURITY_LEVEL_CFM:
case CL_DM_WRITE_INQUIRY_ACCESS_CODE_CFM:
break;
case MESSAGE_MORE_DATA:
{
Source source = ((MessageMoreData *)message)->source;
#ifdef HW_DEV_1163A
/* Check if Aux stream */
if (StreamHidAuxSource() == source)
{
switch (state)
{
case appCabledDisconnected:
/* Move to connecting state */
appSetState(theApp, appCabledConnecting);
default:
/* Handle aux keys */
appHandleDataAux(theApp, source);
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -