Lines Matching +full:all +full:- +full:inputs
4 * SPDX-License-Identifier: Apache-2.0
22 (sys_slist_t *)&((cli)->blob.inputs)->targets, target, blob.n)
26 .app_idx = (cli)->blob.inputs->app_idx, .addr = dst, \
27 .send_ttl = (cli)->blob.inputs->ttl, \
77 if (addr == target->blob.addr) { in target_get()
89 target->status = status; in target_failed()
91 LOG_ERR("Target 0x%04x failed: %u", target->blob.addr, status); in target_failed()
96 if (target->blob.status == BT_MESH_BLOB_SUCCESS) { in target_failed()
97 target->blob.status = BT_MESH_BLOB_ERR_INTERNAL; in target_failed()
100 if (cli->cb && cli->cb->lost_target) { in target_failed()
101 cli->cb->lost_target(cli, target); in target_failed()
109 if (cli->cb && cli->cb->ended) { in dfu_complete()
110 cli->cb->ended(cli, BT_MESH_DFU_SUCCESS); in dfu_complete()
118 cli->xfer.state = STATE_APPLIED; in dfu_applied()
120 if (cli->cb && cli->cb->applied) { in dfu_applied()
121 cli->cb->applied(cli); in dfu_applied()
130 cli->xfer.flags |= FLAG_FAILED; in dfu_failed()
132 if (cli->cb && cli->cb->ended) { in dfu_failed()
133 cli->cb->ended(cli, reason); in dfu_failed()
140 if (cli->req.type != REQ_NONE) { in req_setup()
141 return -EBUSY; in req_setup()
144 cli->req.addr = addr; in req_setup()
145 cli->req.params = params; in req_setup()
146 cli->req.type = type; in req_setup()
155 err = k_sem_take(&cli->req.sem, timeout); in req_wait()
156 cli->req.type = REQ_NONE; in req_wait()
166 if (target->status == BT_MESH_DFU_SUCCESS) { in targets_active()
190 cli->xfer.blob.block_size_log = caps->max_block_size_log; in blob_caps()
191 cli->xfer.blob.chunk_size = caps->max_chunk_size; in blob_caps()
193 /* If mode is not already set and server reported it supports all modes in blob_caps()
195 * was set and server supports all modes, keep old value; set in blob_caps()
198 if (!(cli->xfer.blob.mode & BT_MESH_BLOB_XFER_MODE_ALL)) { in blob_caps()
199 cli->xfer.blob.mode = in blob_caps()
200 caps->modes == BT_MESH_BLOB_XFER_MODE_ALL ? in blob_caps()
201 BT_MESH_BLOB_XFER_MODE_PUSH : caps->modes; in blob_caps()
203 cli->xfer.blob.mode = in blob_caps()
204 caps->modes == BT_MESH_BLOB_XFER_MODE_ALL ? in blob_caps()
205 cli->xfer.blob.mode : caps->modes; in blob_caps()
208 err = bt_mesh_blob_cli_send(b, b->inputs, &cli->xfer.blob, cli->xfer.io); in blob_caps()
223 if ((cli->xfer.state == STATE_CONFIRM || cli->xfer.state == STATE_APPLY) && in blob_lost_target()
224 target->effect == BT_MESH_DFU_EFFECT_UNPROV) { in blob_lost_target()
228 target->blob.status = BT_MESH_BLOB_SUCCESS; in blob_lost_target()
241 cli->xfer.state = STATE_SUSPENDED; in blob_suspended()
243 if (cli->cb && cli->cb->suspended) { in blob_suspended()
244 cli->cb->suspended(cli); in blob_suspended()
253 cli->req.img_cb = NULL; in blob_end()
260 if (cli->xfer.state == STATE_CANCEL) { in blob_end()
261 /* The user cancelled the transfer, DFU will end when all in blob_end()
267 if (cli->xfer.state != STATE_TRANSFER) { in blob_end()
268 LOG_ERR("Blob failed in invalid state %u", cli->xfer.state); in blob_end()
305 blob_cli_broadcast_tx_complete(&cli->blob); in tx_end()
318 cb->end(err, cli); in tx()
335 return tx(cli->mod, ctx, &buf, cb, cli); in info_get()
343 cli->req.img_cnt = 0xff; in send_info_get()
345 info_get(cli, &ctx, 0, cli->req.img_cnt, &send_cb); in send_info_get()
354 if (b->tx.ctx.force_unicast) { in send_update_start()
358 (sys_slist_t *)&((cli)->blob.inputs)->targets, in send_update_start()
366 net_buf_simple_add_u8(&buf, cli->blob.inputs->ttl); in send_update_start()
367 net_buf_simple_add_le16(&buf, cli->blob.inputs->timeout_base); in send_update_start()
368 net_buf_simple_add_le64(&buf, cli->xfer.blob.id); in send_update_start()
369 net_buf_simple_add_u8(&buf, target->img_idx); in send_update_start()
370 net_buf_simple_add_mem(&buf, cli->xfer.slot->metadata, in send_update_start()
371 cli->xfer.slot->metadata_len); in send_update_start()
373 (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); in send_update_start()
384 (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); in send_update_get()
395 (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); in send_update_cancel()
406 (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); in send_update_apply()
426 int img_idx = -1; in initiate()
428 /** If firmware img index is the same for all targets, we can send Firmware Update Start in initiate()
432 if (img_idx == -1) { in initiate()
433 img_idx = target->img_idx; in initiate()
434 } else if (target->img_idx != img_idx) { in initiate()
442 cli->op = BT_MESH_DFU_OP_UPDATE_STATUS; in initiate()
443 cli->xfer.state = STATE_TRANSFER; in initiate()
445 blob_cli_broadcast(&cli->blob, &tx); in initiate()
457 if (bt_mesh_has_addr(target->blob.addr) || in skip_targets_from_broadcast()
458 target->phase == BT_MESH_DFU_PHASE_VERIFY) { in skip_targets_from_broadcast()
459 target->blob.skip = skip; in skip_targets_from_broadcast()
470 if (!bt_mesh_has_addr(target->blob.addr) || !target->blob.skip) { in transfer_skip()
493 /* If distributor only updates itself, or all targets are in Verify phase, in transfer()
500 if (cli->xfer.flags & FLAG_RESUME) { in transfer()
501 cli->xfer.flags ^= FLAG_RESUME; in transfer()
507 } else if (cli->xfer.flags & FLAG_SKIP_CAPS_GET) { in transfer()
508 cli->xfer.flags ^= FLAG_SKIP_CAPS_GET; in transfer()
509 err = bt_mesh_blob_cli_send(b, b->inputs, &cli->xfer.blob, cli->xfer.io); in transfer()
515 err = bt_mesh_blob_cli_caps_get(&cli->blob, cli->blob.inputs); in transfer()
532 cli->xfer.state = STATE_VERIFIED; in refreshed()
546 cli->xfer.state = STATE_REFRESH; in refresh()
547 cli->op = BT_MESH_DFU_OP_UPDATE_STATUS; in refresh()
554 blob_cli_broadcast(&cli->blob, &tx); in refresh()
567 cli->xfer.state = STATE_APPLY; in apply()
568 cli->op = BT_MESH_DFU_OP_UPDATE_STATUS; in apply()
570 blob_cli_broadcast(&cli->blob, &tx); in apply()
593 if ((img->fwid_len != cli->xfer.slot->fwid_len) || in target_img_cb()
594 memcmp(cli->xfer.slot->fwid, img->fwid, img->fwid_len)) { in target_img_cb()
598 target = target_get(cli, ctx->addr); in target_img_cb()
600 LOG_DBG("SUCCESS: 0x%04x applied dfu (as image %u)", ctx->addr, in target_img_cb()
602 target->phase = BT_MESH_DFU_PHASE_APPLY_SUCCESS; in target_img_cb()
603 blob_cli_broadcast_rsp(&cli->blob, &target->blob); in target_img_cb()
605 LOG_WRN("Target 0x%04x not found", ctx->addr); in target_img_cb()
622 cli->op = BT_MESH_DFU_OP_UPDATE_INFO_STATUS; in confirm()
623 cli->req.img_cb = target_img_cb; in confirm()
624 cli->req.ttl = cli->blob.inputs->ttl; in confirm()
626 blob_cli_broadcast(&cli->blob, &tx); in confirm()
635 cli->req.img_cb = NULL; in confirmed()
638 if (target->status != BT_MESH_DFU_SUCCESS) { in confirmed()
645 if (target->effect == BT_MESH_DFU_EFFECT_UNPROV) { in confirmed()
646 if (!target->blob.acked) { in confirmed()
651 LOG_DBG("Target 0x%04x still provisioned", target->blob.addr); in confirmed()
652 target->phase = BT_MESH_DFU_PHASE_APPLY_FAIL; in confirmed()
654 } else if (!target->blob.acked) { in confirmed()
655 LOG_DBG("Target 0x%04x failed to respond", target->blob.addr); in confirmed()
656 target->phase = BT_MESH_DFU_PHASE_APPLY_FAIL; in confirmed()
658 } else if (target->status == BT_MESH_DFU_SUCCESS) { in confirmed()
664 cli->xfer.state = STATE_IDLE; in confirmed()
665 cli->xfer.flags = FLAG_COMPLETED; in confirmed()
667 if (cli->cb && cli->cb->confirmed) { in confirmed()
668 cli->cb->confirmed(cli); in confirmed()
685 cli->op = BT_MESH_DFU_OP_UPDATE_STATUS; in cancel()
687 blob_cli_broadcast(&cli->blob, &tx); in cancel()
694 cli->xfer.flags |= FLAG_CANCELLED; in cancelled()
705 struct bt_mesh_dfu_cli *cli = mod->rt->user_data; in handle_status()
715 if (cli->req.type == REQ_STATUS && cli->req.addr == ctx->addr) { in handle_status()
716 if (cli->req.params) { in handle_status()
717 struct bt_mesh_dfu_target_status *rsp = cli->req.params; in handle_status()
719 rsp->status = status; in handle_status()
720 rsp->phase = phase; in handle_status()
721 if (buf->len == 13) { in handle_status()
722 rsp->ttl = net_buf_simple_pull_u8(buf); in handle_status()
723 rsp->effect = net_buf_simple_pull_u8(buf) & BIT_MASK(5); in handle_status()
724 rsp->timeout_base = net_buf_simple_pull_le16(buf); in handle_status()
725 rsp->blob_id = net_buf_simple_pull_le64(buf); in handle_status()
726 rsp->img_idx = net_buf_simple_pull_u8(buf); in handle_status()
727 } else if (buf->len) { in handle_status()
728 return -EINVAL; in handle_status()
731 rsp->ttl = 0U; in handle_status()
732 rsp->effect = BT_MESH_DFU_EFFECT_NONE; in handle_status()
733 rsp->timeout_base = 0U; in handle_status()
734 rsp->blob_id = 0U; in handle_status()
735 rsp->img_idx = 0U; in handle_status()
737 k_sem_give(&cli->req.sem); in handle_status()
739 if (cli->op != BT_MESH_DFU_OP_UPDATE_STATUS) { in handle_status()
743 target = target_get(cli, ctx->addr); in handle_status()
745 LOG_WRN("Unknown target 0x%04x", ctx->addr); in handle_status()
746 return -ENOENT; in handle_status()
749 LOG_DBG("%u phase: %u, cur state: %u", status, phase, cli->xfer.state); in handle_status()
751 target->phase = phase; in handle_status()
753 if (cli->xfer.state == STATE_APPLY && phase == BT_MESH_DFU_PHASE_IDLE && in handle_status()
756 blob_cli_broadcast_rsp(&cli->blob, &target->blob); in handle_status()
762 blob_cli_broadcast_rsp(&cli->blob, &target->blob); in handle_status()
766 if (buf->len == 13) { in handle_status()
768 target->effect = net_buf_simple_pull_u8(buf) & BIT_MASK(5); in handle_status()
771 if (net_buf_simple_pull_le64(buf) != cli->xfer.blob.id) { in handle_status()
774 blob_cli_broadcast_rsp(&cli->blob, &target->blob); in handle_status()
778 target->img_idx = net_buf_simple_pull_u8(buf); in handle_status()
780 LOG_DBG("Target 0x%04x receiving transfer", ctx->addr); in handle_status()
781 } else if (buf->len) { in handle_status()
782 return -EINVAL; in handle_status()
785 if (cli->xfer.state == STATE_REFRESH) { in handle_status()
791 target->blob.addr); in handle_status()
794 } else if (cli->xfer.state == STATE_APPLY) { in handle_status()
796 (target->effect == BT_MESH_DFU_EFFECT_UNPROV || in handle_status()
799 target->blob.addr, phase); in handle_status()
801 blob_cli_broadcast_rsp(&cli->blob, &target->blob); in handle_status()
805 } else if (cli->xfer.state == STATE_CONFIRM) { in handle_status()
813 target->blob.addr, phase); in handle_status()
814 target->phase = BT_MESH_DFU_PHASE_APPLY_FAIL; in handle_status()
816 blob_cli_broadcast_rsp(&cli->blob, &target->blob); in handle_status()
819 } else if (cli->xfer.state == STATE_CANCEL) { in handle_status()
820 target->phase = BT_MESH_DFU_PHASE_TRANSFER_CANCELED; in handle_status()
823 blob_cli_broadcast_rsp(&cli->blob, &target->blob); in handle_status()
831 struct bt_mesh_dfu_cli *cli = mod->rt->user_data; in handle_info_status()
836 if (!cli->req.img_cb || in handle_info_status()
837 (cli->req.type == REQ_IMG && cli->req.addr != ctx->addr)) { in handle_info_status()
838 LOG_WRN("Unexpected info status from 0x%04x", ctx->addr); in handle_info_status()
843 if (img_cnt < cli->req.img_cnt) { in handle_info_status()
844 cli->req.img_cnt = img_cnt; in handle_info_status()
850 return -ENOENT; in handle_info_status()
853 LOG_DBG("Image list from 0x%04x from index %u", ctx->addr, idx); in handle_info_status()
855 while (buf->len && cli->req.img_cb && idx < cli->req.img_cnt) { in handle_info_status()
861 if (buf->len < img.fwid_len + 1) { in handle_info_status()
863 return -EINVAL; in handle_info_status()
869 if (buf->len < uri_len) { in handle_info_status()
871 return -EINVAL; in handle_info_status()
888 it = cli->req.img_cb(cli, ctx, idx, img_cnt, &img, in handle_info_status()
889 cli->req.params); in handle_info_status()
891 if (cli->req.type == REQ_IMG) { in handle_info_status()
892 k_sem_give(&cli->req.sem); in handle_info_status()
901 if (idx < cli->req.img_cnt) { in handle_info_status()
902 LOG_DBG("Fetching more images (%u/%u)", idx, cli->req.img_cnt); in handle_info_status()
903 ctx->send_ttl = cli->req.ttl; in handle_info_status()
904 info_get(cli, ctx, idx, cli->req.img_cnt - idx, in handle_info_status()
905 (cli->req.type == REQ_IMG) ? NULL : &send_cb); in handle_info_status()
909 if (cli->req.type == REQ_IMG) { in handle_info_status()
910 k_sem_give(&cli->req.sem); in handle_info_status()
914 /* Confirm-procedure termination: */ in handle_info_status()
915 target = target_get(cli, ctx->addr); in handle_info_status()
917 LOG_WRN("Target 0x%04x failed to apply image: %s", ctx->addr, in handle_info_status()
918 bt_hex(cli->xfer.slot->fwid, cli->xfer.slot->fwid_len)); in handle_info_status()
919 target->phase = BT_MESH_DFU_PHASE_APPLY_FAIL; in handle_info_status()
921 blob_cli_broadcast_rsp(&cli->blob, &target->blob); in handle_info_status()
930 struct bt_mesh_dfu_cli *cli = mod->rt->user_data; in handle_metadata_status()
931 struct bt_mesh_dfu_metadata_status *rsp = cli->req.params; in handle_metadata_status()
937 if (cli->req.type != REQ_METADATA || ctx->addr != cli->req.addr || in handle_metadata_status()
938 idx != rsp->idx) { in handle_metadata_status()
940 ctx->addr, idx); in handle_metadata_status()
941 if (cli->req.type != REQ_METADATA) { in handle_metadata_status()
942 LOG_WRN("Expected %u", cli->req.type); in handle_metadata_status()
944 LOG_WRN("Expected 0x%04x img %u", cli->req.addr, idx); in handle_metadata_status()
950 rsp->status = hdr & BIT_MASK(3); in handle_metadata_status()
951 rsp->effect = (hdr >> 3); in handle_metadata_status()
952 k_sem_give(&cli->req.sem); in handle_metadata_status()
967 struct bt_mesh_dfu_cli *cli = mod->rt->user_data; in dfu_cli_init()
968 cli->mod = mod; in dfu_cli_init()
975 return -EINVAL; in dfu_cli_init()
978 err = bt_mesh_model_extend(mod, cli->blob.mod); in dfu_cli_init()
984 k_sem_init(&cli->req.sem, 0, 1); in dfu_cli_init()
991 struct bt_mesh_dfu_cli *cli = mod->rt->user_data; in dfu_cli_reset()
993 cli->req.type = REQ_NONE; in dfu_cli_reset()
994 cli->req.addr = BT_MESH_ADDR_UNASSIGNED; in dfu_cli_reset()
995 cli->req.img_cnt = 0; in dfu_cli_reset()
996 cli->req.img_cb = NULL; in dfu_cli_reset()
997 cli->xfer.state = STATE_IDLE; in dfu_cli_reset()
998 cli->xfer.flags = 0; in dfu_cli_reset()
1011 const struct bt_mesh_blob_cli_inputs *inputs, in bt_mesh_dfu_cli_send() argument
1018 return -EBUSY; in bt_mesh_dfu_cli_send()
1021 cli->xfer.blob.mode = xfer->mode; in bt_mesh_dfu_cli_send()
1022 cli->xfer.blob.size = xfer->slot->size; in bt_mesh_dfu_cli_send()
1024 if (xfer->blob_id == 0) { in bt_mesh_dfu_cli_send()
1025 int err = bt_rand(&cli->xfer.blob.id, sizeof(cli->xfer.blob.id)); in bt_mesh_dfu_cli_send()
1031 cli->xfer.blob.id = xfer->blob_id; in bt_mesh_dfu_cli_send()
1034 cli->xfer.io = io; in bt_mesh_dfu_cli_send()
1035 cli->blob.inputs = inputs; in bt_mesh_dfu_cli_send()
1036 cli->xfer.slot = xfer->slot; in bt_mesh_dfu_cli_send()
1037 cli->xfer.flags = 0U; in bt_mesh_dfu_cli_send()
1039 if (xfer->blob_params) { in bt_mesh_dfu_cli_send()
1040 cli->xfer.flags |= FLAG_SKIP_CAPS_GET; in bt_mesh_dfu_cli_send()
1041 cli->xfer.blob.block_size_log = xfer->blob_params->block_size_log; in bt_mesh_dfu_cli_send()
1042 cli->xfer.blob.chunk_size = xfer->blob_params->chunk_size; in bt_mesh_dfu_cli_send()
1047 target->status = BT_MESH_DFU_SUCCESS; in bt_mesh_dfu_cli_send()
1048 target->phase = BT_MESH_DFU_PHASE_UNKNOWN; in bt_mesh_dfu_cli_send()
1059 err = bt_mesh_blob_cli_suspend(&cli->blob); in bt_mesh_dfu_cli_suspend()
1061 cli->xfer.state = STATE_SUSPENDED; in bt_mesh_dfu_cli_suspend()
1071 if (cli->xfer.state != STATE_SUSPENDED) { in bt_mesh_dfu_cli_resume()
1072 return -EINVAL; in bt_mesh_dfu_cli_resume()
1075 cli->xfer.flags = FLAG_RESUME; in bt_mesh_dfu_cli_resume()
1079 if (!!target->blob.timedout) { in bt_mesh_dfu_cli_resume()
1080 target->status = BT_MESH_DFU_SUCCESS; in bt_mesh_dfu_cli_resume()
1081 target->phase = BT_MESH_DFU_PHASE_UNKNOWN; in bt_mesh_dfu_cli_resume()
1095 err = req_setup(cli, REQ_STATUS, ctx->addr, NULL); in bt_mesh_dfu_cli_cancel()
1103 err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL); in bt_mesh_dfu_cli_cancel()
1105 cli->req.type = REQ_NONE; in bt_mesh_dfu_cli_cancel()
1112 if (cli->xfer.state == STATE_IDLE) { in bt_mesh_dfu_cli_cancel()
1113 return -EALREADY; in bt_mesh_dfu_cli_cancel()
1116 cli->xfer.state = STATE_CANCEL; in bt_mesh_dfu_cli_cancel()
1117 blob_cli_broadcast_abort(&cli->blob); in bt_mesh_dfu_cli_cancel()
1124 if (cli->xfer.state != STATE_VERIFIED) { in bt_mesh_dfu_cli_apply()
1125 return -EBUSY; in bt_mesh_dfu_cli_apply()
1135 if (cli->xfer.state != STATE_APPLIED) { in bt_mesh_dfu_cli_confirm()
1136 return -EBUSY; in bt_mesh_dfu_cli_confirm()
1139 cli->xfer.state = STATE_CONFIRM; in bt_mesh_dfu_cli_confirm()
1147 if (cli->xfer.state == STATE_TRANSFER) { in bt_mesh_dfu_cli_progress()
1148 return bt_mesh_blob_cli_xfer_progress_active_get(&cli->blob); in bt_mesh_dfu_cli_progress()
1151 if (cli->xfer.state == STATE_IDLE) { in bt_mesh_dfu_cli_progress()
1152 if (cli->xfer.flags & FLAG_COMPLETED) { in bt_mesh_dfu_cli_progress()
1163 return (cli->xfer.state == STATE_TRANSFER || in bt_mesh_dfu_cli_is_busy()
1164 cli->xfer.state == STATE_REFRESH || in bt_mesh_dfu_cli_is_busy()
1165 cli->xfer.state == STATE_APPLY || in bt_mesh_dfu_cli_is_busy()
1166 cli->xfer.state == STATE_CONFIRM) && in bt_mesh_dfu_cli_is_busy()
1167 !(cli->xfer.flags & FLAG_FAILED); in bt_mesh_dfu_cli_is_busy()
1177 if (cli->req.img_cb) { in bt_mesh_dfu_cli_imgs_get()
1178 return -EBUSY; in bt_mesh_dfu_cli_imgs_get()
1181 err = req_setup(cli, REQ_IMG, ctx->addr, NULL); in bt_mesh_dfu_cli_imgs_get()
1186 cli->req.img_cb = cb; in bt_mesh_dfu_cli_imgs_get()
1187 cli->req.params = cb_data; in bt_mesh_dfu_cli_imgs_get()
1188 cli->req.ttl = ctx->send_ttl; in bt_mesh_dfu_cli_imgs_get()
1189 cli->req.img_cnt = max_count; in bt_mesh_dfu_cli_imgs_get()
1191 err = info_get(cli, ctx, 0, cli->req.img_cnt, NULL); in bt_mesh_dfu_cli_imgs_get()
1193 cli->req.img_cb = NULL; in bt_mesh_dfu_cli_imgs_get()
1194 cli->req.type = REQ_NONE; in bt_mesh_dfu_cli_imgs_get()
1200 cli->req.img_cb = NULL; in bt_mesh_dfu_cli_imgs_get()
1212 err = req_setup(cli, REQ_METADATA, ctx->addr, rsp); in bt_mesh_dfu_cli_metadata_check()
1223 if (slot->metadata_len) { in bt_mesh_dfu_cli_metadata_check()
1224 net_buf_simple_add_mem(&buf, slot->metadata, in bt_mesh_dfu_cli_metadata_check()
1225 slot->metadata_len); in bt_mesh_dfu_cli_metadata_check()
1228 rsp->idx = img_idx; in bt_mesh_dfu_cli_metadata_check()
1230 err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL); in bt_mesh_dfu_cli_metadata_check()
1232 cli->req.type = REQ_NONE; in bt_mesh_dfu_cli_metadata_check()
1245 err = req_setup(cli, REQ_STATUS, ctx->addr, rsp); in bt_mesh_dfu_cli_status_get()
1253 err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL); in bt_mesh_dfu_cli_status_get()
1255 cli->req.type = REQ_NONE; in bt_mesh_dfu_cli_status_get()