blob: bf4e948412695a83ab38e204c7e25b155a78f886 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "os/mynewt.h"
#include <cbmem/cbmem.h>
#include "log/log.h"
static int
log_cbmem_append(struct log *log, void *buf, int len)
{
struct cbmem *cbmem;
int rc;
cbmem = (struct cbmem *) log->l_arg;
rc = cbmem_append(cbmem, buf, len);
if (rc != 0) {
goto err;
}
return (0);
err:
return (rc);
}
static int
log_cbmem_append_body(struct log *log, const struct log_entry_hdr *hdr,
const void *body, int body_len)
{
struct cbmem *cbmem;
struct cbmem_scat_gath sg = {
.entries = (struct cbmem_scat_gath_entry[2]) {
{
.flat_buf = hdr,
.flat_len = sizeof *hdr,
},
{
.flat_buf = body,
.flat_len = body_len,
},
},
.count = 2,
};
cbmem = (struct cbmem *) log->l_arg;
return cbmem_append_scat_gath(cbmem, &sg);
}
static int
log_cbmem_append_mbuf(struct log *log, const struct os_mbuf *om)
{
struct cbmem *cbmem;
int rc;
cbmem = (struct cbmem *) log->l_arg;
rc = cbmem_append_mbuf(cbmem, om);
if (rc != 0) {
goto err;
}
return (0);
err:
return (rc);
}
static int
log_cbmem_append_mbuf_body(struct log *log, const struct log_entry_hdr *hdr,
const struct os_mbuf *om)
{
struct cbmem *cbmem;
struct cbmem_scat_gath sg = {
.entries = (struct cbmem_scat_gath_entry[2]) {
{
.flat_buf = hdr,
.flat_len = sizeof *hdr,
},
{
.om = om,
},
},
.count = 2,
};
cbmem = (struct cbmem *) log->l_arg;
return cbmem_append_scat_gath(cbmem, &sg);
}
static int
log_cbmem_read(struct log *log, void *dptr, void *buf, uint16_t offset,
uint16_t len)
{
struct cbmem *cbmem;
struct cbmem_entry_hdr *hdr;
int rc;
cbmem = (struct cbmem *) log->l_arg;
hdr = (struct cbmem_entry_hdr *) dptr;
rc = cbmem_read(cbmem, hdr, buf, offset, len);
return (rc);
}
static int
log_cbmem_read_mbuf(struct log *log, void *dptr, struct os_mbuf *om,
uint16_t offset, uint16_t len)
{
struct cbmem *cbmem;
struct cbmem_entry_hdr *hdr;
int rc;
cbmem = (struct cbmem *) log->l_arg;
hdr = (struct cbmem_entry_hdr *) dptr;
rc = cbmem_read_mbuf(cbmem, hdr, om, offset, len);
return (rc);
}
static int
log_cbmem_walk(struct log *log, log_walk_func_t walk_func,
struct log_offset *log_offset)
{
struct cbmem *cbmem;
struct cbmem_entry_hdr *hdr;
struct cbmem_iter iter;
int rc;
cbmem = (struct cbmem *) log->l_arg;
rc = cbmem_lock_acquire(cbmem);
if (rc != 0) {
goto err;
}
/*
* if timestamp for request is < 1, return last log entry
*/
if (log_offset->lo_ts < 0) {
hdr = cbmem->c_entry_end;
if (hdr != NULL) {
rc = walk_func(log, log_offset, (void *)hdr, hdr->ceh_len);
}
} else {
cbmem_iter_start(cbmem, &iter);
while (1) {
hdr = cbmem_iter_next(cbmem, &iter);
if (!hdr) {
break;
}
rc = walk_func(log, log_offset, (void *)hdr, hdr->ceh_len);
if (rc == 1) {
break;
}
}
}
rc = cbmem_lock_release(cbmem);
if (rc != 0) {
goto err;
}
return (0);
err:
return (rc);
}
static int
log_cbmem_flush(struct log *log)
{
struct cbmem *cbmem;
int rc;
cbmem = (struct cbmem *) log->l_arg;
rc = cbmem_flush(cbmem);
if (rc != 0) {
goto err;
}
return (0);
err:
return (rc);
}
#if MYNEWT_VAL(LOG_STORAGE_INFO)
static int
log_cbmem_storage_info(struct log *log, struct log_storage_info *info)
{
struct cbmem *cbmem;
uint32_t size;
uint32_t used;
cbmem = (struct cbmem *)log->l_arg;
size = cbmem->c_buf_end - cbmem->c_buf;
used = (uint32_t)cbmem->c_entry_end + cbmem->c_entry_end->ceh_len -
(uint32_t)cbmem->c_entry_start;
if ((int32_t)used < 0) {
used += size;
}
info->size = size;
info->used = used;
return 0;
}
#endif
const struct log_handler log_cbmem_handler = {
.log_type = LOG_TYPE_MEMORY,
.log_read = log_cbmem_read,
.log_read_mbuf = log_cbmem_read_mbuf,
.log_append = log_cbmem_append,
.log_append_body = log_cbmem_append_body,
.log_append_mbuf = log_cbmem_append_mbuf,
.log_append_mbuf_body = log_cbmem_append_mbuf_body,
.log_walk = log_cbmem_walk,
.log_flush = log_cbmem_flush,
#if MYNEWT_VAL(LOG_STORAGE_INFO)
.log_storage_info = log_cbmem_storage_info,
#endif
};