Files
OpenCellular/common/blob.c
Bill Richardson 45d19984ec Cr50: Add usb_blob handler framework
This adds a new task and endpoints to handle large opaque (to the
USB) chunks of data. The expected use case is that the USB
endpoint accepts bytes from the host and passes them blindly to
the blob-handling task. At some point, the blob-handling task may
wish to send bytes back to the host. What those bytes are and
what they mean is determined at higher levels of abstraction.

BUG=chrome-os-partner:40969
BRANCH=none
TEST=make buildall

This CL doesn't enable the blob-handler; it just makes it
available. The next CL will enable and test it.

Change-Id: I6eba8e8010466e71efe9c5e06848b9f403df835f
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/275131
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2015-06-04 19:33:00 +00:00

114 lines
2.7 KiB
C

/* Copyright 2015 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.
*/
/* Handle an opaque blob of data */
#include "blob.h"
#include "common.h"
#include "console.h"
#include "printf.h"
#include "queue.h"
#include "task.h"
#include "util.h"
#define CPRINTS(format, args...) cprints(CC_USB, format, ## args)
#define INCOMING_QUEUE_SIZE 100
#define OUTGOING_QUEUE_SIZE 100
static void incoming_add(struct queue_policy const *queue_policy, size_t count)
{
task_wake(TASK_ID_BLOB);
}
static void incoming_remove(struct queue_policy const *queue_policy,
size_t count)
{
blob_is_ready_for_more_bytes();
}
static struct queue_policy const incoming_policy = {
.add = incoming_add,
.remove = incoming_remove,
};
static void outgoing_add(struct queue_policy const *queue_policy, size_t count)
{
blob_is_ready_to_emit_bytes();
}
static void outgoing_remove(struct queue_policy const *queue_policy,
size_t count)
{
/* we don't care */
}
static struct queue_policy const outgoing_policy = {
.add = outgoing_add,
.remove = outgoing_remove,
};
static struct queue const incoming_q = QUEUE(INCOMING_QUEUE_SIZE, uint8_t,
incoming_policy);
static struct queue const outgoing_q = QUEUE(OUTGOING_QUEUE_SIZE, uint8_t,
outgoing_policy);
/* Call this to send data to the blob-handler */
size_t put_bytes_to_blob(uint8_t *buffer, size_t count)
{
return QUEUE_ADD_UNITS(&incoming_q, buffer, count);
}
/* Call this to get data back fom the blob-handler */
size_t get_bytes_from_blob(uint8_t *buffer, size_t count)
{
return QUEUE_REMOVE_UNITS(&outgoing_q, buffer, count);
}
#define WEAK_FUNC(FOO) \
void __ ## FOO(void) {} \
void FOO(void) \
__attribute__((weak, alias(STRINGIFY(CONCAT2(__, FOO)))))
/* Default callbacks for outsiders */
WEAK_FUNC(blob_is_ready_for_more_bytes);
WEAK_FUNC(blob_is_ready_to_emit_bytes);
/* Do the magic */
void blob_task(void)
{
static uint8_t buf[INCOMING_QUEUE_SIZE];
size_t count, i;
task_id_t me = task_get_current();
while (1) {
CPRINTS("task %d waiting for events...", me);
task_wait_event(-1);
CPRINTS("task %d awakened!", me);
count = QUEUE_REMOVE_UNITS(&incoming_q, buf, sizeof(buf));
CPRINTS("task %d gets: count=%d buf=((%s))", me, count, buf);
/*
* Just to have something to test to begin with, we'll
* implement "tr a-zA-Z A-Za-z" and return the result.
*/
for (i = 0; i < count; i++) {
char tmp = buf[i];
if (tmp >= 'a' && tmp <= 'z')
buf[i] = tmp - ('a' - 'A');
else if (tmp >= 'A' && tmp <= 'Z')
buf[i] = tmp + ('a' - 'A');
}
count = QUEUE_ADD_UNITS(&outgoing_q, buf, count);
CPRINTS("task %d puts: count=%d buf=((%s))", me, buf);
}
}