diff options
Diffstat (limited to 'common/blob.c')
-rw-r--r-- | common/blob.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/common/blob.c b/common/blob.c new file mode 100644 index 0000000000..5e563598a3 --- /dev/null +++ b/common/blob.c @@ -0,0 +1,113 @@ +/* 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); + } +} |