/****************************************************************************
Copyright (C) Cambridge Silicon Radio 2002
FILE
protocol.c - processing of HID protocol events
MODIFICATION HISTORY
*****************************************************************************/
#include
#include
#include
#include "mouse.h"
/*
Globals
*/
extern DEVICE_STATE_T dev_state;
/*
Process a HIDCONTROL command
*/
void handleControl(const HID_CONTROL_IND_T *prim)
{
switch (prim->op)
{
/*
Entering suspend mode.
To save power, we will disconnect and reconnect when we
the mouse is moved. The Host should support this because
we have RemoteWake and ReconnectInitiate set in our service record.
*/
case HID_COP_SUSPEND:
disconnect(FALSE);
break;
/*
This shouldn't happen as we are disconnected during suspend!
*/
case HID_COP_EXITSUSPEND:
break;
default:
}
}
/*
The Host has sent us a report on either the control or interrupt channel.
The mouse has no output reports so we reject it.
*/
void handleSetReport(const HID_SET_REPORT_IND_T *prim)
{
MAKE_MSG(HID_SET_REPORT_RSP);
/* pass back the identifier */
msg->identifier = prim->identifier;
/* reply unsupported */
msg->result = RES_UNSUPPORTED;
/* free the report */
free(prim->data);
/* send reply */
MessagePut(0,msg);
}
/*
The Host has requested that we change our protocol.
Store the new protocol and respond with success.
*/
void handleSetProtocol(const HID_SET_PROTOCOL_IND_T *prim)
{
MAKE_MSG(HID_SET_PROTOCOL_RSP);
/* store the protocol */
dev_state.protocol = prim->protocol;
msg->result = RES_SUCCESS;
MessagePut(0,msg);
}
/*
The Host has requested our current protocol.
Respond with success and send our protocol.
*/
void handleGetProtocol(const HID_GET_PROTOCOL_IND_T *prim)
{
MAKE_MSG(HID_GET_PROTOCOL_RSP);
prim = prim;
msg->result = RES_SUCCESS;
msg->protocol = dev_state.protocol;
MessagePut(0,msg);
}
/*
The Host has requested that we change our idle rate.
We are a mouse and don't support this, return UNSUPPORTED.
*/
void handleSetIdle(const HID_SET_IDLE_IND_T *prim)
{
MAKE_MSG(HID_SET_IDLE_RSP);
/* keep compiler happy */
prim = prim;
msg->result = RES_UNSUPPORTED;
MessagePut(0,msg);
}
/*
The Host has requested our current idle rate.
We are a mouse and don't support this, return UNSUPPORTED
*/
void handleGetIdle(const HID_GET_IDLE_IND_T *prim)
{
MAKE_MSG(HID_GET_IDLE_RSP);
prim = prim;
msg->result = RES_UNSUPPORTED;
MessagePut(0,msg);
}
/*
The Host has requested a report.
Mouse reports are sent without our knowledge
so we do not know the current state.
This is usually called on startup, so returning
no buttons down and no movement is probably acceptable.
*/
void handleGetReport(const HID_GET_REPORT_IND_T *prim)
{
MAKE_MSG(HID_GET_REPORT_RSP);
/* Check that it is asking for an INPUT report,
we don't support any other report types. */
if (prim->report_type != HIDREPORT_INPUT)
{
/* return invalid param for any other report type */
msg->result = RES_INVALIDPARAM;
}
else
{
/*
We only have one report which has an ID of 2.
This will also be the case in boot mode.
*/
if (prim->report_id == 2)
{
/*
we don't know the current state, so we send
a "empty report"
*/
msg->report_type = HIDREPORT_INPUT;
msg->data = (uint8_t *)malloc(5*sizeof(uint8_t));
msg->data[0] = 2;
msg->data[1] = 0;
msg->data[2] = 0;
msg->data[3] = 0;
msg->data[4] = 0;
/* clip length to only send what fits in Host's buffer */
if (prim->buffer_size < 5)
msg->report_length = prim->buffer_size;
else
msg->report_length = 5;
/* return succesful */
msg->result = RES_SUCCESS;
}
else
/* this is not a valid ID */
msg->result = RES_INVALIDID;
}
MessagePut(0,msg);
}