Files
OpenCellular/common/message.c
David Hendricks e56ba2e689 Update message protocol length byte to include postamble
This simply changes the constant '4' to MSG_PROTO_BYTES, which
includes the postamble. This helps reduce magic constant values
used in processing a packet.

BUG=chrome-os-partner:8975
TEST=tested on daisy (with kernel mkbp driver change)

Signed-off-by: David Hendricks <dhendrix@chromium.org>
Change-Id: Id4634076ad63f45783354179dfebea4fd450fc1e
2012-04-23 14:05:41 -07:00

94 lines
2.2 KiB
C

/*
* This handles incoming commands and provides responses.
*
* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* EC <--> AP message handling.
*/
#include "board.h"
#include "message.h"
#include "keyboard_scan.h"
#include "util.h"
/* Our ID message - Matrix KeyBoard Protocol */
static const char proto_id[] = "Google Chrome MKBP v1";
/**
* Get the response to a given command
*
* @param cmd Command byte to respond to
* @param buffp Buffer to use for data, or it can be updated to
* point to a new buffer
* @param max_len Number of bytes free at *buffp for the response.
* If the supplied buffer is used, this size must not
* be exceeded.
* @return number of bytes in response (which is in *buffp), or -1 on error
*/
static int message_get_response(int cmd, uint8_t **buffp, int max_len)
{
/*
* Invalid commands are ignored, just returning a stream of 0xff
* bytes.
*/
switch (cmd & MSG_CMD_MASK) {
case CMDC_NOP:
return 0;
case CMDC_ID:
*buffp = (char *)proto_id;
return sizeof(proto_id) - 1;
case CMDC_KEY_STATE:
return keyboard_get_scan(buffp, max_len);
default:
return -1;
}
return 0;
}
int message_process_cmd(int cmd, uint8_t *out_msg, int max_len)
{
uint8_t *msg;
int msg_len;
int need_copy;
int sum = 0;
int len;
int i;
msg = out_msg + MSG_HEADER_BYTES;
msg_len = message_get_response(cmd, &msg, max_len - MSG_PROTO_BYTES);
if (msg_len < 0)
return msg_len;
/*
* We add MSG_PROTO_BYTES bytes of overhead: truncate the reply
* if needed.
*/
if (msg_len + MSG_PROTO_BYTES > max_len)
msg_len = max_len - MSG_PROTO_BYTES;
len = msg_len + MSG_PROTO_BYTES;
ASSERT(msg_len >= 0 && msg_len < 0xffff);
need_copy = msg != out_msg + MSG_HEADER_BYTES;
ASSERT(!need_copy ||
msg + msg_len < out_msg ||
msg > out_msg + sizeof(out_msg));
out_msg[0] = MSG_HEADER;
out_msg[1] = len & 0xff;
out_msg[2] = (len >> 8) & 0xff;
sum += MSG_HEADER + len + (len >> 8);
for (i = 0; i < msg_len; i++) {
if (need_copy)
out_msg[i + 3] = msg[i];
sum += msg[i];
}
out_msg[i + 3] = sum & 0xff;
out_msg[i + 4] = MSG_PREAMBLE;
return msg_len + MSG_PROTO_BYTES;
}