Lines Matching +full:- +full:sc
4 * SPDX-License-Identifier: Apache-2.0
53 OSDP_CP_ERR_GENERIC = -1,
54 OSDP_CP_ERR_NO_DATA = -2,
55 OSDP_CP_ERR_RETRY_CMD = -3,
56 OSDP_CP_ERR_CAN_YIELD = -4,
57 OSDP_CP_ERR_INPROG = -5,
58 OSDP_CP_ERR_UNKNOWN = -6,
66 if (k_mem_slab_alloc(&pd->cmd.slab, (void **)&cmd, K_MSEC(100))) { in cp_cmd_alloc()
67 LOG_ERR("Memory allocation time-out"); in cp_cmd_alloc()
75 k_mem_slab_free(&pd->cmd.slab, (void *)cmd); in cp_cmd_free()
80 sys_slist_append(&pd->cmd.queue, &cmd->node); in cp_cmd_enqueue()
87 node = sys_slist_peek_head(&pd->cmd.queue); in cp_cmd_dequeue()
89 return -1; in cp_cmd_dequeue()
91 sys_slist_remove(&pd->cmd.queue, NULL, node); in cp_cmd_dequeue()
102 strncpy(addr_buf, CONFIG_OSDP_PD_ADDRESS_LIST, sizeof(addr_buf) - 1); in osdp_extract_address()
103 addr_buf[sizeof(addr_buf) - 1] = '\0'; in osdp_extract_address()
107 if (*s2 != '\0') { /* tok must be number-ish */ in osdp_extract_address()
108 return -1; in osdp_extract_address()
114 return (pd_offset == CONFIG_OSDP_NUM_CONNECTED_PD) ? 0 : -1; in osdp_extract_address()
136 max_len -= data_off; in cp_build_command()
141 switch (pd->cmd_id) { in cp_build_command()
146 buf[len++] = pd->cmd_id; in cp_build_command()
152 buf[len++] = pd->cmd_id; in cp_build_command()
158 buf[len++] = pd->cmd_id; in cp_build_command()
164 buf[len++] = pd->cmd_id; in cp_build_command()
170 buf[len++] = pd->cmd_id; in cp_build_command()
176 buf[len++] = pd->cmd_id; in cp_build_command()
183 buf[len++] = pd->cmd_id; in cp_build_command()
190 buf[len++] = pd->cmd_id; in cp_build_command()
197 cmd = (struct osdp_cmd *)pd->ephemeral_data; in cp_build_command()
198 buf[len++] = pd->cmd_id; in cp_build_command()
199 buf[len++] = cmd->output.output_no; in cp_build_command()
200 buf[len++] = cmd->output.control_code; in cp_build_command()
201 buf[len++] = BYTE_0(cmd->output.timer_count); in cp_build_command()
202 buf[len++] = BYTE_1(cmd->output.timer_count); in cp_build_command()
208 cmd = (struct osdp_cmd *)pd->ephemeral_data; in cp_build_command()
209 buf[len++] = pd->cmd_id; in cp_build_command()
210 buf[len++] = cmd->led.reader; in cp_build_command()
211 buf[len++] = cmd->led.led_number; in cp_build_command()
213 buf[len++] = cmd->led.temporary.control_code; in cp_build_command()
214 buf[len++] = cmd->led.temporary.on_count; in cp_build_command()
215 buf[len++] = cmd->led.temporary.off_count; in cp_build_command()
216 buf[len++] = cmd->led.temporary.on_color; in cp_build_command()
217 buf[len++] = cmd->led.temporary.off_color; in cp_build_command()
218 buf[len++] = BYTE_0(cmd->led.temporary.timer_count); in cp_build_command()
219 buf[len++] = BYTE_1(cmd->led.temporary.timer_count); in cp_build_command()
221 buf[len++] = cmd->led.permanent.control_code; in cp_build_command()
222 buf[len++] = cmd->led.permanent.on_count; in cp_build_command()
223 buf[len++] = cmd->led.permanent.off_count; in cp_build_command()
224 buf[len++] = cmd->led.permanent.on_color; in cp_build_command()
225 buf[len++] = cmd->led.permanent.off_color; in cp_build_command()
231 cmd = (struct osdp_cmd *)pd->ephemeral_data; in cp_build_command()
232 buf[len++] = pd->cmd_id; in cp_build_command()
233 buf[len++] = cmd->buzzer.reader; in cp_build_command()
234 buf[len++] = cmd->buzzer.control_code; in cp_build_command()
235 buf[len++] = cmd->buzzer.on_count; in cp_build_command()
236 buf[len++] = cmd->buzzer.off_count; in cp_build_command()
237 buf[len++] = cmd->buzzer.rep_count; in cp_build_command()
240 cmd = (struct osdp_cmd *)pd->ephemeral_data; in cp_build_command()
241 if (!check_buf_len(CMD_TEXT_LEN + cmd->text.length, max_len)) { in cp_build_command()
244 buf[len++] = pd->cmd_id; in cp_build_command()
245 buf[len++] = cmd->text.reader; in cp_build_command()
246 buf[len++] = cmd->text.control_code; in cp_build_command()
247 buf[len++] = cmd->text.temp_time; in cp_build_command()
248 buf[len++] = cmd->text.offset_row; in cp_build_command()
249 buf[len++] = cmd->text.offset_col; in cp_build_command()
250 buf[len++] = cmd->text.length; in cp_build_command()
251 memcpy(buf + len, cmd->text.data, cmd->text.length); in cp_build_command()
252 len += cmd->text.length; in cp_build_command()
258 cmd = (struct osdp_cmd *)pd->ephemeral_data; in cp_build_command()
259 buf[len++] = pd->cmd_id; in cp_build_command()
260 buf[len++] = cmd->comset.address; in cp_build_command()
261 buf[len++] = BYTE_0(cmd->comset.baud_rate); in cp_build_command()
262 buf[len++] = BYTE_1(cmd->comset.baud_rate); in cp_build_command()
263 buf[len++] = BYTE_2(cmd->comset.baud_rate); in cp_build_command()
264 buf[len++] = BYTE_3(cmd->comset.baud_rate); in cp_build_command()
269 LOG_ERR("Cannot perform KEYSET without SC!"); in cp_build_command()
275 cmd = (struct osdp_cmd *)pd->ephemeral_data; in cp_build_command()
276 if (cmd->keyset.length != 16) { in cp_build_command()
280 buf[len++] = pd->cmd_id; in cp_build_command()
283 if (cmd->keyset.type == 1) { /* SCBK */ in cp_build_command()
284 memcpy(buf + len, cmd->keyset.data, 16); in cp_build_command()
285 } else if (cmd->keyset.type == 0) { /* master_key */ in cp_build_command()
286 osdp_compute_scbk(pd, cmd->keyset.data, buf + len); in cp_build_command()
288 LOG_ERR("Unknown key type (%d)", cmd->keyset.type); in cp_build_command()
299 return -1; in cp_build_command()
304 buf[len++] = pd->cmd_id; in cp_build_command()
305 memcpy(buf + len, pd->sc.cp_random, 8); in cp_build_command()
314 return -1; in cp_build_command()
320 buf[len++] = pd->cmd_id; in cp_build_command()
321 memcpy(buf + len, pd->sc.cp_cryptogram, 16); in cp_build_command()
326 LOG_ERR("Unknown/Unsupported CMD(%02x)", pd->cmd_id); in cp_build_command()
333 * When SC active and current cmd is not a handshake (<= SCS_14) in cp_build_command()
352 pd->reply_id = buf[pos++]; in cp_decode_response()
353 len--; /* consume reply id from the head */ in cp_decode_response()
355 switch (pd->reply_id) { in cp_decode_response()
367 buf[pos], pd->cmd_id); in cp_decode_response()
374 pd->id.vendor_code = buf[pos++]; in cp_decode_response()
375 pd->id.vendor_code |= buf[pos++] << 8; in cp_decode_response()
376 pd->id.vendor_code |= buf[pos++] << 16; in cp_decode_response()
378 pd->id.model = buf[pos++]; in cp_decode_response()
379 pd->id.version = buf[pos++]; in cp_decode_response()
381 pd->id.serial_number = buf[pos++]; in cp_decode_response()
382 pd->id.serial_number |= buf[pos++] << 8; in cp_decode_response()
383 pd->id.serial_number |= buf[pos++] << 16; in cp_decode_response()
384 pd->id.serial_number |= buf[pos++] << 24; in cp_decode_response()
386 pd->id.firmware_version = buf[pos++] << 16; in cp_decode_response()
387 pd->id.firmware_version |= buf[pos++] << 8; in cp_decode_response()
388 pd->id.firmware_version |= buf[pos++]; in cp_decode_response()
401 pd->cap[t1].function_code = t1; in cp_decode_response()
402 pd->cap[t1].compliance_level = buf[pos++]; in cp_decode_response()
403 pd->cap[t1].num_items = buf[pos++]; in cp_decode_response()
406 /* post-capabilities hooks */ in cp_decode_response()
408 if (pd->cap[t2].compliance_level & 0x01) { in cp_decode_response()
452 pd->address = t1; in cp_decode_response()
453 pd->baud_rate = temp32; in cp_decode_response()
457 if (len < REPLY_KEYPPAD_DATA_LEN || !ctx->event_callback) { in cp_decode_response()
463 if ((len - REPLY_KEYPPAD_DATA_LEN) != event.keypress.length) { in cp_decode_response()
467 ctx->event_callback(ctx->event_callback_arg, pd->idx, &event); in cp_decode_response()
471 if (len < REPLY_RAW_DATA_LEN || !ctx->event_callback) { in cp_decode_response()
479 event.cardread.direction = 0; /* un-specified */ in cp_decode_response()
481 if (t1 != (len - REPLY_RAW_DATA_LEN)) { in cp_decode_response()
485 ctx->event_callback(ctx->event_callback_arg, pd->idx, &event); in cp_decode_response()
489 if (len < REPLY_FMT_DATA_LEN || !ctx->event_callback) { in cp_decode_response()
497 if (event.cardread.length != (len - REPLY_FMT_DATA_LEN) || in cp_decode_response()
502 ctx->event_callback(ctx->event_callback_arg, pd->idx, &event); in cp_decode_response()
514 if (sc_is_active(pd) || pd->cmd_id != CMD_CHLNG) { in cp_decode_response()
521 memcpy(pd->sc.pd_client_uid, buf + pos, 8); in cp_decode_response()
522 memcpy(pd->sc.pd_random, buf + pos + 8, 8); in cp_decode_response()
523 memcpy(pd->sc.pd_cryptogram, buf + pos + 16, 16); in cp_decode_response()
533 if (sc_is_active(pd) || pd->cmd_id != CMD_SCRYPT) { in cp_decode_response()
540 memcpy(pd->sc.r_mac, buf + pos, 16); in cp_decode_response()
547 pd->cmd_id, pd->reply_id); in cp_decode_response()
553 pd->cmd_id, pd->reply_id); in cp_decode_response()
556 if (pd->cmd_id != CMD_POLL) { in cp_decode_response()
557 LOG_DBG("CMD(%02x) REPLY(%02x)", pd->cmd_id, pd->reply_id); in cp_decode_response()
568 len = osdp_phy_packet_init(pd, pd->rx_buf, sizeof(pd->rx_buf)); in cp_build_packet()
574 ret = cp_build_command(pd, pd->rx_buf, sizeof(pd->rx_buf)); in cp_build_packet()
581 len = osdp_phy_packet_finalize(pd, pd->rx_buf, len, sizeof(pd->rx_buf)); in cp_build_packet()
586 pd->rx_buf_len = len; in cp_build_packet()
596 if (pd->channel.flush) { in cp_send_command()
597 pd->channel.flush(pd->channel.data); in cp_send_command()
600 ret = pd->channel.send(pd->channel.data, pd->rx_buf, pd->rx_buf_len); in cp_send_command()
601 if (ret != pd->rx_buf_len) { in cp_send_command()
603 pd->rx_buf_len, ret); in cp_send_command()
608 if (pd->cmd_id != CMD_POLL) { in cp_send_command()
610 osdp_dump(NULL, pd->rx_buf, pd->rx_buf_len); in cp_send_command()
622 buf = pd->rx_buf + pd->rx_buf_len; in cp_process_reply()
623 remaining = sizeof(pd->rx_buf) - pd->rx_buf_len; in cp_process_reply()
625 len = pd->channel.recv(pd->channel.data, buf, remaining); in cp_process_reply()
629 pd->rx_buf_len += len; in cp_process_reply()
632 if (pd->cmd_id != CMD_POLL) { in cp_process_reply()
634 osdp_dump(NULL, pd->rx_buf, pd->rx_buf_len); in cp_process_reply()
638 err = osdp_phy_check_packet(pd, pd->rx_buf, pd->rx_buf_len, &len); in cp_process_reply()
655 len = osdp_phy_decode_packet(pd, pd->rx_buf, len, &buf); in cp_process_reply()
662 len = pd->rx_buf_len - one_pkt_len; in cp_process_reply()
664 memmove(pd->rx_buf, pd->rx_buf + one_pkt_len, len); in cp_process_reply()
666 pd->rx_buf_len = len; in cp_process_reply()
682 pd->state = state; in cp_set_state()
689 pd->wait_ms = 0; in cp_set_online()
690 pd->tstamp = 0; in cp_set_online()
696 pd->state = OSDP_CP_STATE_OFFLINE; in cp_set_offline()
697 pd->tstamp = osdp_millis_now(); in cp_set_offline()
698 if (pd->wait_ms == 0) { in cp_set_offline()
699 pd->wait_ms = 1000; /* retry after 1 second initially */ in cp_set_offline()
701 pd->wait_ms <<= 1; in cp_set_offline()
702 if (pd->wait_ms > OSDP_ONLINE_RETRY_WAIT_MAX_MS) { in cp_set_offline()
703 pd->wait_ms = OSDP_ONLINE_RETRY_WAIT_MAX_MS; in cp_set_offline()
712 osdp_millis_since(pd->sc_tstamp) > OSDP_PD_SC_RETRY_MS); in cp_sc_should_retry()
722 switch (pd->phy_state) { in cp_phy_state_update()
724 elapsed = osdp_millis_since(pd->phy_tstamp); in cp_phy_state_update()
728 pd->phy_state = OSDP_CP_PHY_STATE_SEND_CMD; in cp_phy_state_update()
738 pd->cmd_id = cmd->id; in cp_phy_state_update()
739 memcpy(pd->ephemeral_data, cmd, sizeof(struct osdp_cmd)); in cp_phy_state_update()
741 /* fall-thru */ in cp_phy_state_update()
745 pd->cmd_id); in cp_phy_state_update()
750 LOG_ERR("Failed to send CMD(%d)", pd->cmd_id); in cp_phy_state_update()
751 pd->phy_state = OSDP_CP_PHY_STATE_ERR; in cp_phy_state_update()
756 pd->phy_state = OSDP_CP_PHY_STATE_REPLY_WAIT; in cp_phy_state_update()
757 pd->rx_buf_len = 0; /* reset buf_len for next use */ in cp_phy_state_update()
758 pd->phy_tstamp = osdp_millis_now(); in cp_phy_state_update()
765 pd->sc_tstamp = osdp_millis_now(); in cp_phy_state_update()
768 pd->phy_state = OSDP_CP_PHY_STATE_IDLE; in cp_phy_state_update()
773 pd->phy_tstamp = osdp_millis_now(); in cp_phy_state_update()
774 pd->phy_state = OSDP_CP_PHY_STATE_WAIT; in cp_phy_state_update()
778 osdp_millis_since(pd->phy_tstamp) > OSDP_RESP_TOUT_MS) { in cp_phy_state_update()
781 pd->cmd_id); in cp_phy_state_update()
783 pd->rx_buf_len = 0; in cp_phy_state_update()
784 if (pd->channel.flush) { in cp_phy_state_update()
785 pd->channel.flush(pd->channel.data); in cp_phy_state_update()
788 pd->phy_state = OSDP_CP_PHY_STATE_ERR; in cp_phy_state_update()
813 c->id = cmd; in cp_cmd_dispatcher()
815 if (c->id == CMD_KEYSET) { in cp_cmd_dispatcher()
816 memcpy(&c->keyset, pd->ephemeral_data, sizeof(c->keyset)); in cp_cmd_dispatcher()
840 soft_fail = (pd->state == OSDP_CP_STATE_SC_CHLNG); in state_update()
842 /* phy state error -- cleanup */ in state_update()
843 if (pd->state != OSDP_CP_STATE_OFFLINE && in state_update()
851 switch (pd->state) { in state_update()
855 LOG_INF("Retry SC after retry timeout"); in state_update()
860 if (osdp_millis_since(pd->tstamp) < OSDP_PD_POLL_TIMEOUT_MS) { in state_update()
864 pd->tstamp = osdp_millis_now(); in state_update()
868 if (osdp_millis_since(pd->tstamp) > pd->wait_ms) { in state_update()
883 if (pd->reply_id != REPLY_PDID) { in state_update()
885 STRINGIFY(CMD_ID), pd->reply_id); in state_update()
895 if (pd->reply_id != REPLY_PDCAP) { in state_update()
897 STRINGIFY(CMD_CAP), pd->reply_id); in state_update()
922 LOG_INF("SC Failed. Online without SC"); in state_update()
923 pd->sc_tstamp = osdp_millis_now(); in state_update()
930 pd->phy_state = 0; /* soft reset phy state */ in state_update()
931 LOG_WRN("SC Failed. Retry with SCBK-D"); in state_update()
934 if (pd->reply_id != REPLY_CCRYPT) { in state_update()
935 LOG_ERR("CHLNG failed. Online without SC"); in state_update()
936 pd->sc_tstamp = osdp_millis_now(); in state_update()
947 if (pd->reply_id != REPLY_RMAC_I) { in state_update()
948 LOG_ERR("SCRYPT failed. Online without SC"); in state_update()
950 pd->sc_tstamp = osdp_millis_now(); in state_update()
955 LOG_WRN("SC ACtive with SCBK-D. Set SCBK"); in state_update()
959 LOG_INF("SC Active"); in state_update()
960 pd->sc_tstamp = osdp_millis_now(); in state_update()
965 keyset = (struct osdp_cmd_keyset *)pd->ephemeral_data; in state_update()
967 memcpy(keyset->data, pd->sc.scbk, 16); in state_update()
968 keyset->type = 1; in state_update()
970 keyset->type = 0; in state_update()
971 memcpy(keyset->data, ctx->sc_master_key, 16); in state_update()
973 keyset->length = 16; in state_update()
978 if (pd->reply_id == REPLY_NAK) { in state_update()
979 LOG_WRN("Failed to set SCBK; continue with SCBK-D"); in state_update()
984 pd->seq_number = -1; in state_update()
1007 return -1; in osdp_cp_send_command_keyset()
1018 res = -1; in osdp_cp_send_command_keyset()
1021 cmd[i]->id = CMD_KEYSET; in osdp_cp_send_command_keyset()
1022 memcpy(&cmd[i]->keyset, p, sizeof(struct osdp_cmd_keyset)); in osdp_cp_send_command_keyset()
1039 struct osdp_cmd *c = (struct osdp_cmd *)pd->ephemeral_data; in cp_keyset_complete()
1043 memcpy(pd->sc.scbk, c->keyset.data, 16); in cp_keyset_complete()
1045 LOG_INF("SCBK set; restarting SC to verify new SCBK"); in cp_keyset_complete()
1067 return -1; in osdp_setup()
1069 memcpy(ctx->sc_master_key, key, 16); in osdp_setup()
1074 /* --- Exported Methods --- */
1080 ctx->event_callback = cb; in osdp_cp_set_event_callback()
1081 ctx->event_callback_arg = arg; in osdp_cp_set_event_callback()
1092 return -1; in osdp_cp_send_command()
1094 if (osdp_to_pd(ctx, pd)->state != OSDP_CP_STATE_ONLINE) { in osdp_cp_send_command()
1096 return -1; in osdp_cp_send_command()
1099 switch (cmd->id) { in osdp_cp_send_command()
1117 return osdp_cp_send_command_keyset(&cmd->keyset); in osdp_cp_send_command()
1120 LOG_ERR("Invalid CMD_ID:%d", cmd->id); in osdp_cp_send_command()
1121 return -1; in osdp_cp_send_command()
1126 return -1; in osdp_cp_send_command()
1129 p->id = cmd_id; /* translate to internal */ in osdp_cp_send_command()