You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/06/17 20:55:04 UTC
[1/2] incubator-mynewt-core git commit: sys/reboot;
package depends on log.
Repository: incubator-mynewt-core
Updated Branches:
refs/heads/develop 39dd36c86 -> a9af204e1
sys/reboot; package depends on log.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/ee39d2ba
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/ee39d2ba
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/ee39d2ba
Branch: refs/heads/develop
Commit: ee39d2ba2168fc035d106f804932a17f4aceddac
Parents: 39dd36c
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Jun 17 13:51:39 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Jun 17 13:51:39 2016 -0700
----------------------------------------------------------------------
sys/reboot/pkg.yml | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ee39d2ba/sys/reboot/pkg.yml
----------------------------------------------------------------------
diff --git a/sys/reboot/pkg.yml b/sys/reboot/pkg.yml
index 8142ffb..45fba7d 100644
--- a/sys/reboot/pkg.yml
+++ b/sys/reboot/pkg.yml
@@ -30,6 +30,7 @@ pkg.deps:
- libs/util
- libs/testutil
- sys/fcb
+ - sys/log
- libs/imgmgr
pkg.req_apis:
- console
[2/2] incubator-mynewt-core git commit: libs/boot_serial;
first cut at doing image upgrade over serial in bootloader.
Posted by ma...@apache.org.
libs/boot_serial; first cut at doing image upgrade over serial
in bootloader.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/a9af204e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/a9af204e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/a9af204e
Branch: refs/heads/develop
Commit: a9af204e1a2cfb99cf2819cf71712ba02bd632ed
Parents: ee39d2b
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Jun 17 13:53:49 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Jun 17 13:53:49 2016 -0700
----------------------------------------------------------------------
.../include/boot_serial/boot_serial.h | 33 ++
libs/boot_serial/pkg.yml | 37 ++
libs/boot_serial/src/boot_serial.c | 403 +++++++++++++++++++
libs/boot_serial/src/boot_serial_priv.h | 61 +++
libs/boot_serial/src/test/boot_test.c | 232 +++++++++++
5 files changed, 766 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9af204e/libs/boot_serial/include/boot_serial/boot_serial.h
----------------------------------------------------------------------
diff --git a/libs/boot_serial/include/boot_serial/boot_serial.h b/libs/boot_serial/include/boot_serial/boot_serial.h
new file mode 100644
index 0000000..67fa415
--- /dev/null
+++ b/libs/boot_serial/include/boot_serial/boot_serial.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#ifndef __BOOT_SERIAL_H__
+#define __BOOT_SERIAL_H__
+
+/*
+ * Create a task for uploading image0 over serial.
+ *
+ * Task opens console serial port and waits for download command.
+ * Return code 0 means new image was uploaded, non-zero means that
+ * there was an error.
+ */
+int boot_serial_task_init(struct os_task *task, uint8_t prio,
+ os_stack_t *stack, uint16_t stack_size, int max_input);
+
+#endif /* __BOOT_SERIAL_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9af204e/libs/boot_serial/pkg.yml
----------------------------------------------------------------------
diff --git a/libs/boot_serial/pkg.yml b/libs/boot_serial/pkg.yml
new file mode 100644
index 0000000..4c1002a
--- /dev/null
+++ b/libs/boot_serial/pkg.yml
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+pkg.name: libs/boot_serial
+pkg.description: The boot_serial library is used when downloading image over serial port.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+ - boot
+ - bootloader
+
+pkg.features:
+ - BOOT_SERIAL
+
+pkg.deps:
+ - hw/hal
+ - libs/os
+ - libs/testutil
+ - libs/util
+pkg.req_apis:
+ - console
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9af204e/libs/boot_serial/src/boot_serial.c
----------------------------------------------------------------------
diff --git a/libs/boot_serial/src/boot_serial.c b/libs/boot_serial/src/boot_serial.c
new file mode 100644
index 0000000..9323aa3
--- /dev/null
+++ b/libs/boot_serial/src/boot_serial.c
@@ -0,0 +1,403 @@
+/*
+ * 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 <assert.h>
+#include <stddef.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#include <bsp/bsp.h>
+
+#include <hal/flash_map.h>
+#include <hal/hal_flash.h>
+#include <hal/hal_system.h>
+
+#include <os/endian.h>
+#include <os/os.h>
+#include <os/os_malloc.h>
+
+#include <console/console.h>
+
+#include <util/base64.h>
+#include <util/crc16.h>
+
+#include <bootutil/image.h>
+
+#include "boot_serial/boot_serial.h"
+#include "boot_serial_priv.h"
+
+#define BOOT_SERIAL_OUT_MAX 48
+
+static uint32_t curr_off;
+static uint32_t img_size;
+static struct nmgr_hdr *bs_hdr;
+
+static void boot_serial_output(char *data, int len);
+
+/*
+ * Looks for 'name' from NULL-terminated json data in buf.
+ * Returns pointer to first character of value for that name.
+ * Returns NULL if 'name' is not found.
+ */
+char *
+bs_find_val(char *buf, char *name)
+{
+ char *ptr;
+
+ ptr = strstr(buf, name);
+ if (!ptr) {
+ return NULL;
+ }
+ ptr += strlen(name);
+
+ while (*ptr != '\0') {
+ if (*ptr != ':' && !isspace(*ptr)) {
+ break;
+ }
+ ++ptr;
+ }
+ if (*ptr == '\0') {
+ ptr = NULL;
+ }
+ return ptr;
+}
+
+/*
+ * List images.
+ */
+static void
+bs_list(char *buf, int len)
+{
+ char *ptr;
+ struct image_header hdr;
+ uint8_t tmpbuf[64];
+ const struct flash_area *fap = NULL;
+ int good_img, need_comma = 0;
+ int rc;
+ int i;
+
+ ptr = os_malloc(BOOT_SERIAL_OUT_MAX);
+ if (!ptr) {
+ return;
+ }
+ len = snprintf(ptr, BOOT_SERIAL_OUT_MAX, "{\"images\":[");
+ for (i = FLASH_AREA_IMAGE_0; i <= FLASH_AREA_IMAGE_1; i++) {
+ rc = flash_area_open(i, &fap);
+ if (rc) {
+ continue;
+ }
+
+ flash_area_read(fap, 0, &hdr, sizeof(hdr));
+
+ if (hdr.ih_magic == IMAGE_MAGIC &&
+ bootutil_img_validate(&hdr, fap->fa_flash_id, fap->fa_off,
+ tmpbuf, sizeof(tmpbuf)) == 0) {
+ good_img = 1;
+ } else {
+ good_img = 0;
+ }
+ if (good_img) {
+ len += snprintf(ptr + len, BOOT_SERIAL_OUT_MAX - len,
+ "%c\"%u.%u.%u.%u\"", need_comma ? ',' : ' ',
+ hdr.ih_ver.iv_major, hdr.ih_ver.iv_minor, hdr.ih_ver.iv_revision,
+ (unsigned int)hdr.ih_ver.iv_build_num);
+ }
+ flash_area_close(fap);
+ }
+ len += snprintf(ptr + len, BOOT_SERIAL_OUT_MAX - len, "]}");
+ boot_serial_output(ptr, len);
+ os_free(ptr);
+}
+
+/*
+ * Image upload request.
+ */
+static void
+bs_upload(char *buf, int len)
+{
+ char *ptr;
+ char *data_ptr;
+ uint32_t off, data_len = 0;
+ const struct flash_area *fap = NULL;
+ int rc;
+
+ /*
+ * should be json inside
+ */
+ ptr = bs_find_val(buf, "\"off\"");
+ if (!ptr) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+ off = strtoul(ptr, NULL, 10);
+
+ if (off == 0) {
+ ptr = bs_find_val(buf, "\"len\"");
+ if (!ptr) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+ data_len = strtoul(ptr, NULL, 10);
+
+ }
+ data_ptr = bs_find_val(buf, "\"data\"");
+ if (!data_ptr) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+ if (*data_ptr != '"') {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+ ++data_ptr;
+ data_ptr = strsep(&data_ptr, "\"");
+ if (!data_ptr) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+
+ len = base64_decode(data_ptr, data_ptr);
+ if (len <= 0) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+
+ rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap);
+ if (rc) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+
+ if (off == 0) {
+ curr_off = 0;
+ if (data_len > fap->fa_size) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+ rc = flash_area_erase(fap, 0, fap->fa_size);
+ if (rc) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+ img_size = data_len;
+ }
+ if (off != curr_off) {
+ rc = 0;
+ goto out;
+ }
+ rc = flash_area_write(fap, curr_off, data_ptr, len);
+ if (rc) {
+ rc = NMGR_ERR_EINVAL;
+ goto out;
+ }
+ curr_off += len;
+
+out:
+ ptr = os_malloc(BOOT_SERIAL_OUT_MAX);
+ if (!ptr) {
+ return;
+ }
+ if (rc == 0) {
+ len = snprintf(ptr, BOOT_SERIAL_OUT_MAX, "{\"rc\":%d,\"off\":%u}",
+ rc, (int)curr_off);
+ } else {
+ len = snprintf(ptr, BOOT_SERIAL_OUT_MAX, "{\"rc\":%d}", rc);
+ }
+ boot_serial_output(ptr, len);
+ os_free(ptr);
+ flash_area_close(fap);
+}
+
+/*
+ * Console echo control. Send empty response, don't do anything.
+ */
+static void
+bs_echo_ctl(char *buf, int len)
+{
+ boot_serial_output(NULL, 0);
+}
+
+/*
+ * Reset, and (presumably) boot to newly uploaded image. Flush console
+ * before restarting.
+ */
+static void
+bs_reset(char *buf, int len)
+{
+ char msg[] = "{\"rc\":0}";
+
+ boot_serial_output(msg, strlen(msg));
+ os_time_delay(250);
+ system_reset();
+}
+
+/*
+ * Parse incoming line of input from console.
+ * Expect newtmgr protocol with serial transport.
+ */
+void
+boot_serial_input(char *buf, int len)
+{
+ int rc;
+ uint16_t crc;
+ uint16_t expected_len;
+ struct nmgr_hdr *hdr;
+
+ if (len < BASE64_ENCODE_SIZE(sizeof(uint16_t) * 2)) {
+ return;
+ }
+ rc = base64_decode(buf, buf);
+ if (rc < 0) {
+ return;
+ }
+ len = rc;
+
+ expected_len = ntohs(*(uint16_t *)buf);
+ buf += sizeof(uint16_t);
+ len -= sizeof(uint16_t);
+
+ len = min(len, expected_len);
+
+ crc = crc16_ccitt(CRC16_INITIAL_CRC, buf, len);
+ if (crc || len <= sizeof(crc)) {
+ return;
+ }
+ len -= sizeof(crc);
+ buf[len] = '\0';
+
+ hdr = (struct nmgr_hdr *)buf;
+ if (len < sizeof(*hdr) ||
+ (hdr->nh_op != NMGR_OP_READ && hdr->nh_op != NMGR_OP_WRITE) ||
+ (ntohs(hdr->nh_len) < len - sizeof(*hdr))) {
+ return;
+ }
+ bs_hdr = hdr;
+ hdr->nh_group = ntohs(hdr->nh_group);
+
+ buf += sizeof(*hdr);
+ len -= sizeof(*hdr);
+
+ /*
+ * Limited support for commands.
+ */
+ if (hdr->nh_group == NMGR_GROUP_ID_IMAGE) {
+ switch (hdr->nh_id) {
+ case IMGMGR_NMGR_OP_LIST:
+ bs_list(buf, len);
+ break;
+ case IMGMGR_NMGR_OP_UPLOAD:
+ bs_upload(buf, len);
+ break;
+ default:
+ break;
+ }
+ } else if (hdr->nh_group == NMGR_GROUP_ID_DEFAULT) {
+ switch (hdr->nh_id) {
+ case NMGR_ID_CONS_ECHO_CTRL:
+ bs_echo_ctl(buf, len);
+ break;
+ case NMGR_ID_RESET:
+ bs_reset(buf, len);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void
+boot_serial_output(char *data, int len)
+{
+ uint16_t crc;
+ uint16_t totlen;
+ char pkt_start[2] = { SHELL_NLIP_PKT_START1, SHELL_NLIP_PKT_START2 };
+ char buf[BOOT_SERIAL_OUT_MAX];
+ char encoded_buf[BASE64_ENCODE_SIZE(BOOT_SERIAL_OUT_MAX)];
+
+ bs_hdr->nh_op++;
+ bs_hdr->nh_len = htons(len);
+ bs_hdr->nh_group = htons(bs_hdr->nh_group);
+
+ crc = crc16_ccitt(CRC16_INITIAL_CRC, bs_hdr, sizeof(*bs_hdr));
+ crc = crc16_ccitt(crc, data, len);
+ crc = htons(crc);
+
+ console_write(pkt_start, sizeof(pkt_start));
+
+ totlen = len + sizeof(*bs_hdr) + sizeof(crc);
+ totlen = htons(totlen);
+
+ memcpy(buf, &totlen, sizeof(totlen));
+ totlen = sizeof(totlen);
+ memcpy(&buf[totlen], bs_hdr, sizeof(*bs_hdr));
+ totlen += sizeof(*bs_hdr);
+ memcpy(&buf[totlen], data, len);
+ totlen += len;
+ memcpy(&buf[totlen], &crc, sizeof(crc));
+ totlen += sizeof(crc);
+ totlen = base64_encode(buf, totlen, encoded_buf, 1);
+ console_write(encoded_buf, totlen);
+ console_write("\n", 1);
+}
+
+/*
+ * Task which waits reading console, expecting to get image over
+ * serial port.
+ */
+static void
+boot_serial(void *arg)
+{
+ int rc;
+ int off;
+ char *buf;
+ int full_line;
+ int max_input = (int)arg;
+
+ rc = console_init(NULL);
+ assert(rc == 0);
+ console_echo(0);
+
+ buf = os_malloc(max_input);
+ assert(buf);
+
+ off = 0;
+ while (1) {
+ rc = console_read(buf + off, max_input - off, &full_line);
+ if (rc <= 0 && !full_line) {
+ continue;
+ }
+ off += rc;
+ if (!full_line) {
+ continue;
+ }
+ if (buf[0] == SHELL_NLIP_PKT_START1 &&
+ buf[1] == SHELL_NLIP_PKT_START2) {
+ boot_serial_input(&buf[2], off - 2);
+ }
+ off = 0;
+ }
+}
+
+int
+boot_serial_task_init(struct os_task *task, uint8_t prio, os_stack_t *stack,
+ uint16_t stack_size, int max_input)
+{
+ return os_task_init(task, "boot", boot_serial, (void *)max_input,
+ prio, OS_WAIT_FOREVER, stack, stack_size);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9af204e/libs/boot_serial/src/boot_serial_priv.h
----------------------------------------------------------------------
diff --git a/libs/boot_serial/src/boot_serial_priv.h b/libs/boot_serial/src/boot_serial_priv.h
new file mode 100644
index 0000000..86ba6c6
--- /dev/null
+++ b/libs/boot_serial/src/boot_serial_priv.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#ifndef __BOOTUTIL_SERIAL_PRIV_H__
+#define __BOOTUTIL_SERIAL_PRIV_H__
+
+/*
+ * From shell.h
+ */
+#define SHELL_NLIP_PKT_START1 6
+#define SHELL_NLIP_PKT_START2 9
+
+/*
+ * From newtmgr.h
+ */
+#define NMGR_ERR_EINVAL 3
+
+#define NMGR_OP_READ 0
+#define NMGR_OP_WRITE 2
+
+#define NMGR_GROUP_ID_DEFAULT 0
+#define NMGR_GROUP_ID_IMAGE 1
+
+#define NMGR_ID_CONS_ECHO_CTRL 1
+#define NMGR_ID_RESET 5
+
+struct nmgr_hdr {
+ uint8_t nh_op; /* NMGR_OP_XXX */
+ uint8_t nh_flags;
+ uint16_t nh_len; /* length of the payload */
+ uint16_t nh_group; /* NMGR_GROUP_XXX */
+ uint8_t nh_seq; /* sequence number */
+ uint8_t nh_id; /* message ID within group */
+};
+
+/*
+ * From imgmgr.h
+ */
+#define IMGMGR_NMGR_OP_LIST 0
+#define IMGMGR_NMGR_OP_UPLOAD 1
+
+
+void boot_serial_input(char *buf, int len);
+
+#endif /* __BOOTUTIL_SERIAL_PRIV_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9af204e/libs/boot_serial/src/test/boot_test.c
----------------------------------------------------------------------
diff --git a/libs/boot_serial/src/test/boot_test.c b/libs/boot_serial/src/test/boot_test.c
new file mode 100644
index 0000000..3859b46
--- /dev/null
+++ b/libs/boot_serial/src/test/boot_test.c
@@ -0,0 +1,232 @@
+/*
+ * 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 <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <util/base64.h>
+#include <util/crc16.h>
+#include <testutil/testutil.h>
+#include <newtmgr/newtmgr.h>
+#include <imgmgr/imgmgr.h>
+#include <hal/hal_flash.h>
+#include <hal/flash_map.h>
+
+#include "../boot_serial_priv.h"
+
+void
+tx_msg(void *src, int len)
+{
+ char *msg;
+ char *enc;
+ int off;
+ uint16_t crc;
+
+ crc = htons(crc16_ccitt(CRC16_INITIAL_CRC, src, len));
+
+ /*
+ * Lazy, malloc a buffer, fill it and send it.
+ */
+ msg = malloc(len + 2 * sizeof(uint16_t));
+ assert(msg);
+
+ *(uint16_t *)msg = ntohs(len + sizeof(uint16_t));
+ off = sizeof(uint16_t);
+ memcpy(&msg[off], src, len);
+ off += len;
+ memcpy(&msg[off], &crc, sizeof(crc));
+ off += sizeof(uint16_t);
+
+ enc = malloc(BASE64_ENCODE_SIZE(off) + 1);
+ assert(enc);
+
+ off = base64_encode(msg, off, enc, 1);
+ assert(off > 0);
+
+ boot_serial_input(enc, off + 1);
+
+ free(enc);
+ free(msg);
+}
+
+TEST_CASE(boot_serial_setup)
+{
+
+}
+
+TEST_CASE(boot_serial_empty_msg)
+{
+ char buf[4];
+ struct nmgr_hdr hdr;
+
+ boot_serial_input(buf, 0);
+
+ tx_msg(buf, 0);
+
+ strcpy(buf, "--");
+ tx_msg(buf, 2);
+
+ memset(&hdr, 0, sizeof(hdr));
+ tx_msg(&hdr, sizeof(hdr));
+
+ hdr.nh_op = NMGR_OP_WRITE;
+
+ tx_msg(&hdr, sizeof(hdr));
+}
+
+TEST_CASE(boot_serial_empty_img_msg)
+{
+ char buf[sizeof(struct nmgr_hdr) + 32];
+ struct nmgr_hdr *hdr;
+
+ hdr = (struct nmgr_hdr *)buf;
+ memset(hdr, 0, sizeof(*hdr));
+ hdr->nh_op = NMGR_OP_WRITE;
+ hdr->nh_group = NMGR_GROUP_ID_IMAGE;
+ hdr->nh_id = IMGMGR_NMGR_OP_UPLOAD;
+ hdr->nh_len = htons(2);
+ strcpy((char *)(hdr + 1), "{}");
+
+ tx_msg(buf, sizeof(*hdr) + 2);
+}
+
+TEST_CASE(boot_serial_img_msg)
+{
+ char img[16];
+ char enc_img[BASE64_ENCODE_SIZE(sizeof(img))];
+ char buf[sizeof(struct nmgr_hdr) + sizeof(enc_img) + 32];
+ int len;
+ int rc;
+ struct nmgr_hdr *hdr;
+ const struct flash_area *fap;
+
+ memset(img, 0xa5, sizeof(img));
+ len = base64_encode(img, sizeof(img), enc_img, 1);
+ assert(len > 0);
+
+ hdr = (struct nmgr_hdr *)buf;
+ memset(hdr, 0, sizeof(*hdr));
+ hdr->nh_op = NMGR_OP_WRITE;
+ hdr->nh_group = NMGR_GROUP_ID_IMAGE;
+ hdr->nh_id = IMGMGR_NMGR_OP_UPLOAD;
+
+ len = sprintf((char *)(hdr + 1), "{\"off\":0,\"len\":16,\"data\":\"%s\"}",
+ enc_img);
+ hdr->nh_len = htons(len);
+
+ len = sizeof(*hdr) + len;
+
+ tx_msg(buf, len);
+
+ /*
+ * Validate contents inside image 0 slot
+ */
+ rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap);
+ assert(rc == 0);
+
+ rc = flash_area_read(fap, 0, enc_img, sizeof(img));
+ assert(rc == 0);
+ assert(!memcmp(enc_img, img, sizeof(img)));
+}
+
+TEST_CASE(boot_serial_upload_bigger_image)
+{
+ char img[256];
+ char enc_img[64];
+ char buf[sizeof(struct nmgr_hdr) + 128];
+ int len;
+ int off;
+ int rc;
+ struct nmgr_hdr *hdr;
+ const struct flash_area *fap;
+ int i;
+
+ for (i = 0; i < sizeof(img); i++) {
+ img[i] = i;
+ }
+
+ for (off = 0; off < sizeof(img); off += 32) {
+ len = base64_encode(&img[off], 32, enc_img, 1);
+ assert(len > 0);
+
+ hdr = (struct nmgr_hdr *)buf;
+ memset(hdr, 0, sizeof(*hdr));
+ hdr->nh_op = NMGR_OP_WRITE;
+ hdr->nh_group = NMGR_GROUP_ID_IMAGE;
+ hdr->nh_id = IMGMGR_NMGR_OP_UPLOAD;
+
+ if (off) {
+ len = sprintf((char *)(hdr + 1), "{\"off\":%d,\"data\":\"%s\"}",
+ off, enc_img);
+ } else {
+ len = sprintf((char *)(hdr + 1), "{\"off\": 0 ,\"len\":%ld, "
+ "\"data\":\"%s\"}", (long)sizeof(img), enc_img);
+ }
+ hdr->nh_len = htons(len);
+
+ len = sizeof(*hdr) + len;
+
+ tx_msg(buf, len);
+ }
+
+ /*
+ * Validate contents inside image 0 slot
+ */
+ rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap);
+ assert(rc == 0);
+
+ for (off = 0; off < sizeof(img); off += sizeof(enc_img)) {
+ rc = flash_area_read(fap, off, enc_img, sizeof(enc_img));
+ assert(rc == 0);
+ assert(!memcmp(enc_img, &img[off], sizeof(enc_img)));
+ }
+}
+
+TEST_SUITE(boot_serial_suite)
+{
+ boot_serial_setup();
+ boot_serial_empty_msg();
+ boot_serial_empty_img_msg();
+ boot_serial_img_msg();
+ boot_serial_upload_bigger_image();
+}
+
+int
+boot_serial_test(void)
+{
+ boot_serial_suite();
+ return tu_any_failed;
+}
+
+#ifdef MYNEWT_SELFTEST
+int
+main(void)
+{
+ tu_config.tc_print_results = 1;
+ tu_init();
+
+ boot_serial_test();
+
+ return tu_any_failed;
+}
+
+#endif