This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2652P: Application issues.

Expert 1910 points
Part Number: CC2652P
Other Parts Discussed in Thread: Z-STACK

Tool/software:

Hi Team,

Use CC2652.  The issue of not being able to connect to the ZIGBEE gateway.

In register_task.c file, when reg_step is ZB_REG_STEP_ZB_CONNECT, 

1. Please help analyze the reason why the ZIGBEE gateway cannot be connected.

2. How to analyze where the program is stuck when the connection causes the watchdog to restart.

The zstackmsg_CmdIDs_DEV_STATE_CHANGE-IND callback displays that the device has entered zstack_DevState-IND_VNet UNAUTH=5, and then the device freezes and restarts,
Only one of the three devices can connect normally, while the other two prototype devices are experiencing stuck issues,

 Bluetooth message.zip

#include "register_task.h"
#include "register.h"

#include "storage.h"
#include "touchboard_device.h"

#include "zigbee_transport_channel.h"
#include "zb_trans_task.h"
#ifdef YD_BLE_APP_SUPPORT
#include "ble_trans_task.h"
#endif
#include "password_task.h"
#include "battery_task.h"

#include "security.h"
#include "calendar.h"
#include "sound_ctrl.h"
#include "sw_timer.h"

#include "log.h"
#include "security.h"
#include "ecc_dsa.h"
#include "dd_protocol_run.h"
#include "device_data.h"
#include "crc16_bd.h"
#include "wall_clock_timer.h"
#include "datetime.h"
#include "battery.h"
#include "zigbee_transport_l2_recv.h"
#include "device_data.h"
#include "dd_string.h"
#include "communicate_common_def.h"
#include "password_task.h"

#define REGISTER_PROCESS_TIMEOUT_MS \
    120000 // 2min���󶨹������ʱʱ�䣬������ʱ�仹û�����������ʱ����ǿ�ƽ���������
#define REGISTER_PREPARE_BIND_HW_CENTER_TIMEOUT_MS \
    15000 // 15s����ǰ����������Ҫ�󶨻�Ϊ����ʱ���������Ժ�������ü����в�������Ϊ������
#define DEFAULT_REGISTER_TIMEOUT_DELAY_MS 12000 // ÿ���󶨽׶�Ĭ�ϵij�ʱʱ��
#define PASSWORD_SYNC_DELAY_MS            8000 // ����ֵͬ���׶γ�ʱʱ��
#define ZIGBEE_SCAN_WAIT_TIMEOUT_DELAY_MS 3000 // ����ɨ��׶γ�ʱʱ��
#define SCAN_RETRY_MAX_TIME               100  // ����ɨ��׶����Դ���
#define SCAN_RETRY_TIME_RELOAD_CODE       6    // ����ɨ��׶�����n�κ��л��̼�
#define STEP_RETRY_MAX_TIME               100  // ÿ���󶨽׶�Ĭ�����Դ���
#define POST_SN_STEP_RETRY_MAX_TIME       3    // �ϱ�SN���кŽ׶����Դ���
#define PWD_SYNC_MAX_TIME                 10   // ����ͬ��(ID�Լ�����ֵ)�׶����Դ���

static dd_uint8_t ecc_private_key[DATA_SZ_ECC_PRIVATE_KEY]
    __attribute__((aligned(4))) = {0}; // ����˽Կ
static dd_uint8_t ecc_public_key[DATA_SZ_ECC_PUBLIC_KEY]
    __attribute__((aligned(4))) = {0}; // ���˹�Կ
static dd_uint8_t ecc_public_key_cloud[DATA_SZ_ECC_PUBLIC_KEY]
    __attribute__((aligned(4))) = {0}; // �ƶ˹�Կ
static dd_uint8_t ecc_eshare_key[DATA_SZ_ECC_SHARE_KEY]
    __attribute__((aligned(4))) = {0}; // ������Կ

static dd_int32_t cur_conn_panid_index = 0; // ��ǰ���ӵ����ض�Ӧ��panid�б��±�
static dd_int32_t cur_conn_panid_count = 0; // ��ǰɨ�赽������panid�б����

static dd_int32_t step_retry_time = 0; // ��ǰ�׶ε����Դ���
static dd_int32_t scan_retry_time =
    0; // ɨ��׶ε����Դ�������step_retry_time���֣�����Ϊ�п��ܵ��˺���׶�ʧ��ʱ��Ҫ���½���ɨ��׶�

static dd_uint32_t register_start_second_counter = 0;

static register_step_cb register_success_cb = NULL; // �󶨳ɹ���Ļص�
static register_step_cb register_fail_cb = NULL;    // ��ʧ�ܺ�Ļص�

static dd_bool_t local_key_is_created = DD_FALSE;

static void set_next_register_step_and_send_task(zb_register_step next_step);

/* �󶨽׶γ�ʱ�Լ�ACK���� */
static void register_process_timeout_handler(void* p_context);
static void register_password_id_sync_ack_rsp(dd_uint16_t err_code);
static void register_password_data_sync_ack_rsp(dd_uint16_t err_code);
static void register_step_timer_handler(void* p_context);

/* �����������ݻص����� */
static void post_sn_response(dd_bool_t is_postSN_success, dd_uint16_t enddevice_id);
static void update_challenge_code(dd_uint8_t* challenge_code);
static void update_transkey(dd_uint8_t* transkey, dd_uint8_t* end_time);
static void start_transkey_update_process(void);
static void register_device(dd_uint8_t* uuid, dd_uint8_t* seed, dd_uint8_t* trans_key);
static void register_unregister(dd_uint32_t cmd_id);
static void register_bind(dd_uint32_t cmd_id);
static void register_unbind(dd_uint32_t cmd_id);
static void register_pwdseed(dd_uint32_t cmd_id, dd_uint8_t* seed, dd_uint8_t* trans_key,
                             dd_uint8_t* uuid);
static void register_remote_service(dd_bool_t success);
static void scan_result(dd_uint16_t* list, dd_int32_t count);
static void connect_result(dd_bool_t is_connected);
// ziroom
static void set_pub_key_response(const dd_uint8_t* data, dd_uint16_t length, dd_uint8_t seq_id);
static void set_share_key_sign_response(const dd_uint16_t crc_result_cloud, dd_uint8_t seq_id);
static void set_recv_sign_result_response(dd_uint8_t sign_result_cloud, dd_uint8_t seq_id);
static void set_recv_update_timestamp_response(dd_uint32_t time_val, dd_uint32_t cipher_counter, dd_uint8_t seq_id);
static void set_recv_post_device_info_response(dd_uint8_t response_id);

/* TASK������ */
static void register_task_register_handler(register_msg_context* context);
static void register_task_save_info_handler(register_msg_context* context);
static void register_task_check_pwdseed(register_msg_context* context);
static void register_task_check_transkey(register_msg_context* context);
static void register_task_update_seed(register_msg_context* context);
static void register_task_update_transkey(register_msg_context* context);
static void register_task_button_start(register_msg_context* context);
static void register_task_expand_cmd_start(register_msg_context* context);
static void register_task_restart_start(register_msg_context* context);
static void register_task_get_challenge_code(register_msg_context* context);
static void register_task_post_auth_code(register_msg_context* context);
static void register_task_save_transkey(register_msg_context* context);

static void register_dump_all_key(void)
{
    uint8_t i;
    dd_uint8_t* tmp_eshare_key = NULL;

    tmp_eshare_key = get_dm_sharekey();
    LOG("device_public_key:");
    for(i = 0;i < DATA_SZ_ECC_PUBLIC_KEY;i++) {
        LOG("0x%02x", ecc_public_key[i]);
    }
    LOG("device_private_key:");
    for(i = 0;i < DATA_SZ_ECC_PRIVATE_KEY;i++) {
        LOG("0x%02x", ecc_private_key[i]);
    }
    LOG("public_key_cloud:");
    for(i = 0;i < DATA_SZ_ECC_PUBLIC_KEY;i++) {
        LOG("0x%02x", ecc_public_key_cloud[i]);
    }
    LOG("ecc_eshare_key:");
    for(i = 0;i < DATA_SZ_ECC_SHARE_KEY;i++) {
        LOG("0x%02x", tmp_eshare_key[i]);
    }
    LOG_HIGHLIGHT("current key type:%d",get_key_type());
}

/* ������һ�󶨽׶β�����TASK */
static void set_next_register_step_and_send_task(zb_register_step next_step) {
    if (set_zb_next_reg_step(next_step)) {
        SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);
    }
}
/* ������һ�󶨽׶β�����TASK */
static void set_register_step_and_send_task(zb_register_step next_step) {
    set_zb_reg_step(next_step);
    SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);
}

/* ���������̳�ʱ��Ĵ������ʱ��ʧ�� */
static void register_process_timeout_handler(void* p_context) {
    LOG("register_process_timeout,ZIGBEE FOR REGISTER FAIL");
    SW_TIMER_STOP(SW_TIMER_ID_REGISTER_STEP);

    if (get_dm_is_register_status()) // �ڰ󶨽׶�
    {
        dd_int32_t reg_step = get_zb_reg_step();
        if (reg_step != ZB_REG_STEP_FINISH) {
            LOG("current reg_step:%d. Set step to ZB_REG_STEP_FAIL!",get_zb_reg_step());
            set_zb_reg_step(ZB_REG_STEP_FAIL);
        }

        SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);
    } else // ���ڰ󶨽׶Σ�����Ҫ������ս��
    {
        reset_dm_challenge_code();
    }
}
#if 0
/* ����IDͬ��ACK�����Լ���ʱ���� */
static void register_password_id_sync_ack_rsp(dd_uint16_t err_code) {
    LOG_HIGHLIGHT("register_password_id_sync_ack_rsp=%d", err_code);

    if (RSP_CODE_TIMEOUT == err_code) {
        if (step_retry_time < PWD_SYNC_MAX_TIME) {
            step_retry_time++;
            SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);
        }
    } else if (RSP_CODE_SUCCESS == err_code) {
        set_next_register_step_and_send_task(ZB_REG_STEP_SYNC_PASSWORD_DATA);
        step_retry_time = 0;
    }
}

/* ��������ͬ��ACK�����Լ���ʱ���� */
static void register_password_data_sync_ack_rsp(dd_uint16_t err_code) {
    LOG_HIGHLIGHT("register_password_data_sync_ack_rsp=%d", err_code);

    if (RSP_CODE_SUCCESS == err_code) {
        step_retry_time = 0;

        if (!is_need_cont_pwd_sync()) {
            set_zb_reg_step(ZB_REG_STEP_SEND_REGISTER_FINISH);
        }

        SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);
    } else if (RSP_CODE_TIMEOUT == err_code) // send fail
    {
        if (step_retry_time < PWD_SYNC_MAX_TIME) {
            reset_pwd_sync_count();
            step_retry_time++;
            SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);
        }
    }
}
#endif
/* �󶨹����е����󶨲��賬ʱ�Ĵ��� */
static void register_step_timer_handler(void* p_context) {
    SW_TIMER_STOP(SW_TIMER_ID_REGISTER_STEP);
    dd_int32_t reg_step = get_zb_reg_step();
    dd_bool_t register_fail = DD_FALSE;

    LOG_HIGHLIGHT("[Register Timer]Register timeout step=%d", reg_step);

    //���ڰ󶨹����У��󶨵�׼���׶�
    if (!get_dm_is_register_status()) {
        switch (reg_step) {
            case ZB_REG_STEP_PREPARE_BIND_HW_CENTER: {
                // 15s ��ʱʱ�䵽 ׼���󶨻�Ϊ����ʧ�� ���´��ڴ��и��°�ģʽ
                update_zb_bind_mode_from_flash();
                set_zb_reg_step(ZB_REG_STEP_NONE);
                break;
            }

            default:
                break;
        }

        return;
    }

    // ���ݰ󶨽׶Σ��ж��Ƿ���Ҫ����
    switch (reg_step) {
        case ZB_REG_STEP_GET_ZB_SCAN_LIST: {
            if (scan_retry_time >= SCAN_RETRY_MAX_TIME) {
                register_fail = DD_TRUE;
            }
            break;
        }

        case ZB_REG_STEP_ZB_CONNECT: {
            if ((cur_conn_panid_index + 1) >=
                cur_conn_panid_count) // ����Ѿ�������������ɨ�赽������
            {
                if (scan_retry_time < SCAN_RETRY_MAX_TIME) {
                    set_zb_reg_step(ZB_REG_STEP_GET_ZB_SCAN_LIST); // �˻ص�ɨ��׶�
                } else {
                    register_fail = DD_TRUE;
                }
            }
            break;
        }

        case ZB_REG_STEP_WAIT_SHARE_KEY_SIGN: {
            set_zb_reg_step(ZB_REG_STEP_POST_PUB_KEY);
            step_retry_time++;
            break;
        }

        case ZB_REG_STEP_WAIT_SIGN_RESULT: {
            set_zb_reg_step(ZB_REG_STEP_POST_SHARE_KEY_SIGN);
            step_retry_time++;
            break;
        }

        case ZB_REG_STEP_WAIT_GET_DEV_INFO: {
            set_zb_reg_step(ZB_REG_STEP_POST_REQUEST_TIMESTAMP);
            step_retry_time++;
            break;
        }

        default: {
            if (step_retry_time >= STEP_RETRY_MAX_TIME) {
                register_fail = DD_TRUE;
            }
            break;
        }
    }

    if (step_retry_time >= STEP_RETRY_MAX_TIME) {
        register_fail = DD_TRUE;
    }
    // ������Դ����������ޣ����ʧ��
    if (register_fail) {
        set_zb_reg_step(ZB_REG_STEP_FAIL);
    }

    SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);
}

/* �����ʱ�������л�.(�˽ӿڵ�ǰֻ������¼������ʱ�䣬���µ��ô����޸�) */
void register_reboot_reload_app(void) {
    dd_uint32_t millisecond = get_second_wallclock();
    millisecond = (millisecond - register_start_second_counter) * 1000;

    dd_uint32_t used_millisecond = st_read_register_time_used_millisecond();

    used_millisecond = used_millisecond + millisecond;

    LOG_HIGHLIGHT("register_reboot_reload_app:used second = %ds", used_millisecond / 1000);

    if (used_millisecond >= REGISTER_PROCESS_TIMEOUT_MS) {
        register_process_timeout_handler(NULL);
        return;
    }

    st_write_register_time_used_millisecond(used_millisecond);
    //st_write_sys_reset_flag(NORMAL_RESET);
    // reboot_to_boot_reload_app1();
}
#if 0
/* ���������·���post sn��� */
static void post_sn_response(dd_bool_t is_postSN_success, dd_uint16_t enddevice_id) {
    if (!get_dm_is_register_status()) // ���ڰ󶨹��̣�ֱ�ӷ���
        return;

    if (is_postSN_success) {
        if (get_zb_reg_step() > ZB_REG_STEP_POST_SN) // �����ϱ�SN�׶Σ�ֱ�ӷ��أ��п������ظ�����
            return;

        SOUND_DIDI();
        step_retry_time = 0;

#if (SECURITY_USE_ROOT_KEY == 1)
        set_next_register_step_and_send_task(ZB_REG_STEP_GET_CHALLENGE_CODE);
#else
        set_register_step_and_send_task(ZB_REG_STEP_SEND_REGISTER_DEVICE);
#endif

        set_dm_enddevice_id(enddevice_id);
        LOG_HIGHLIGHT("is_postSN_success,enddevice id=%d", enddevice_id);
    } else {
        LOG_HIGHLIGHT("SN is illegal!!!");
        if (cur_conn_panid_count > 0 && cur_conn_panid_index < cur_conn_panid_count) {
            set_register_step_and_send_task(ZB_REG_STEP_ZB_CONNECT);
        } else {
            set_register_step_and_send_task(ZB_REG_STEP_GET_ZB_RESET);
        }
    }
}
#endif
static void set_pub_key_response(const dd_uint8_t* cloud_pubkey, dd_uint16_t length,
                                 dd_uint8_t seq_id) {
    dd_uint8_t err_code = ZB_ZIROOM_CODE_SUCCESS;
    dd_bool_t need_update_cloud_pubkey = DD_TRUE;

    /* �Ѿ�������ƶ˹�Կ���յ���������յ����ƶ˹�Կ��ԭ����ͬ�������Ƕ�����
    ���������ٴ�announce,��Ҫ�����ƶ˹�Կ��sharekey�����ƶ˱���ƥ��;
    �����ԭ����ͬ�������Ƕ�0x80�ظ���error_code��ʧ�ˣ����»ظ����������� */
    if (flash_public_key_cloud_is_valid() == DD_TRUE) {
        if (0 == memcmp(get_dm_public_key_cloud(), cloud_pubkey, DATA_SZ_ECC_PUBLIC_KEY))
        {
            /* �յ���ͬ���ƶ˹�Կ���������̣�����������ƶ˹�Կ */
            LOG("Repeated acceptance cloud_pubkey");
            need_update_cloud_pubkey = DD_FALSE;
        } else {
            /* �յ���ͬ���ƶ˹�Կ����Ҫ��������sharekey */
            local_key_is_created = DD_FALSE;
			LOG("update cloud_pubkey!");
        }
    } else if (get_zb_reg_step() != ZB_REG_STEP_WAIT_CLOUD_PUB) {
        LOG("set_pub_key_response step error");
        return;
    }

    if (need_update_cloud_pubkey == DD_TRUE) {
        /* �����ƶ˹�Կ������ram */
        DD_MEMCPY(ecc_public_key_cloud, cloud_pubkey, DATA_SZ_ECC_PUBLIC_KEY);
        /* �����ƶ˹�Կ������flash */
        set_dm_public_key_cloud(ecc_public_key_cloud, DATA_SZ_ECC_PUBLIC_KEY);
        st_write_public_key_cloud(get_dm_public_key_cloud());
    }
    
    ziroom_protocol_response_send(CHANNEL_ZB_ID, ZIROOM_PROTOCOL_VERSION, ZB_ZIROOM_SET_PUB_KEY,
                                  &err_code, sizeof(err_code), DD_FALSE, DD_FALSE, seq_id);

    /* ������һ�󶨲��� */
    set_next_register_step_and_send_task(ZB_REG_STEP_POST_PUB_KEY);

    return;
}

static void set_share_key_sign_response(const dd_uint16_t crc_result_cloud, dd_uint8_t seq_id) {
    dd_uint16_t crc_result = 0;
    dd_uint8_t err_code = ZB_ZIROOM_CODE_SUCCESS;
    zb_register_step reg_step;

    reg_step = get_zb_reg_step();
    /* ������Ӧ�󶨽׶Σ�ֱ�ӷ��أ��п������ظ�����;������������ܴ���15�׶�ʱ�յ�0x82������ */
    if ((reg_step != ZB_REG_STEP_WAIT_SHARE_KEY_SIGN) && (reg_step != ZB_REG_STEP_POST_PUB_KEY)) {
        LOG("set_share_key_sign_response step error");
        return;
    }

    crc_result = bd_crc16(crc_result, ecc_public_key, DATA_SZ_ECC_PUBLIC_KEY);

    LOG("***set_share_key_sign_response:crc_result:0x%x,crc_result_cloud:0x%x", crc_result,
        crc_result_cloud);

    if (crc_result == crc_result_cloud) {
        /* ��ǩһ�£��ظ�errorcode��������һ������ */
        set_register_step_and_send_task(ZB_REG_STEP_POST_SHARE_KEY_SIGN);
    } else {
        /* ��ǩ�쳣���ظ�errorcode������������ */
        set_zb_reg_step(ZB_REG_STEP_FAIL);
        err_code = ZB_ZIROOM_CODE_SHARE_KEY_SIGN_FAIL;
        register_dump_all_key();
    }

    ziroom_protocol_response_send(CHANNEL_ZB_ID, ZIROOM_PROTOCOL_VERSION,
                                  ZB_ZIROOM_SET_SHARE_KEY_SIGN, &err_code, sizeof(err_code),
                                  DD_FALSE, DD_FALSE, seq_id);

    return;
}

static void set_recv_sign_result_response(dd_uint8_t sign_result_cloud, dd_uint8_t seq_id) {
    dd_uint8_t err_code = ZB_ZIROOM_CODE_SUCCESS;
    zb_register_step reg_step;

    LOG_HIGHLIGHT("register step = %d",get_zb_reg_step());
    reg_step = get_zb_reg_step();
    /* ������Ӧ�׶Σ�ֱ�ӷ��أ��п������ظ�����;������������ܴ���17�׶�ʱ�յ�0x82������ */
    if ((reg_step != ZB_REG_STEP_WAIT_SIGN_RESULT) && (reg_step != ZB_REG_STEP_POST_SHARE_KEY_SIGN)) {
        LOG("set_recv_sign_result_response step error");
        return;
    }

    LOG("set_recv_sign_result_response sign_result_cloud:0x%x", sign_result_cloud);
    if (sign_result_cloud == ZB_ZIROOM_CODE_SUCCESS) {
        /* ��ǩ�ɹ������浽ram���󶨳ɹ��󱣴�esharekey��flash��������������һ�󶨽׶� */
        set_dm_sharekey(ecc_eshare_key, DATA_SZ_ECC_SHARE_KEY);
    } else {
        /* ��ǩʧ�ܣ����������� */
        err_code = ZB_ZIROOM_CODE_SHARE_KEY_SIGN_FAIL;
        set_zb_reg_step(ZB_REG_STEP_FAIL);
        register_dump_all_key();
    }

    ziroom_protocol_response_send(CHANNEL_ZB_ID, ZIROOM_PROTOCOL_VERSION, ZB_ZIROOM_SET_SIGN_RESULT,
                                  &err_code, sizeof(err_code), DD_FALSE, DD_FALSE, seq_id);

    if (sign_result_cloud == ZB_ZIROOM_CODE_SUCCESS) {
        set_register_step_and_send_task(ZB_REG_STEP_POST_REQUEST_TIMESTAMP);
    }
        
    return;
}

static void set_recv_update_timestamp_response(dd_uint32_t time_val,dd_uint32_t cipher_counter,  dd_uint8_t seq_id) {
    dd_uint8_t err_code = ZB_ZIROOM_CODE_INVALID_OPT;
    dd_int32_t i = 3;
    dd_int32_t ret = -1;
    dd_uint8_t ntime[6] = {0};
    time_union_t time_union;
    dd_uint32_t local_cipher_counter = 0;
    local_cipher_counter = st_read_ziroom_cipher_counter();
    LOG("set_recv_update_timestamp_response local_cipher_counter 0x%x",local_cipher_counter);
    if(local_cipher_counter > 0xFFFFFFF0){
        st_reset_ziroom_cipher_counter();
        local_cipher_counter = 0;
    }
     LOG("local_cipher_counter 0x%x,cipher_counter %d",local_cipher_counter,cipher_counter);
    if(cipher_counter > 0xFFFFFFF0){
        st_reset_ziroom_cipher_counter();
        err_code = ZB_ZIROOM_CODE_INVALID_OPT;
      }
    else if(cipher_counter > local_cipher_counter){
        //ʱ���ת��Ϊ����ʱ��
        linux_localtime_buffer(ntime, time_val);
        set_alink_time(ntime, 6);
#if (RANDOM_PWD_ENABLE == 1) //���¶�̬����
        SEND_TASK_TYPE(TASK_ID_PASSWORD, MSG_PASSWORD_GEN_RANDOM);
#endif

#if (ONE_TIME_RANDOM_PWD_ENABLE == 1) // ����һ���Զ�̬����
       SEND_TASK_TYPE(TASK_ID_PASSWORD, MSG_PASSWORD_GEN_ONE_TIME_RANDOM);
#endif
        st_write_ziroom_cipher_counter(cipher_counter);
        err_code = ZB_ZIROOM_CODE_SUCCESS;
    }

    ret = ziroom_protocol_response_send(CHANNEL_ZB_ID, ZIROOM_PROTOCOL_VERSION,
                                        ZB_ZIROOM_UPDATE_TIMESTAMP, &err_code, sizeof(err_code),
                                        DD_FALSE, DD_FALSE, seq_id);

    return;
}
static void zb_register_device_info_ack_rsp(dd_uint16_t err_code) {
    LOG("[%s] zb_register_device_info_ack_rsp=%d[CB]", "ZB", err_code);

    if (RSP_CODE_SUCCESS == err_code) {
        /* ��ǰ������ڰ󶨽׶�ZB_REG_STEP_WAIT_GET_DEV_INFO���������һ������ */
        if( (get_zb_reg_step() == ZB_REG_STEP_WAIT_GET_DEV_INFO &&  get_dm_is_register_status())){
            LOG_HIGHLIGHT("register step = %d",get_zb_reg_step());
            set_next_register_step_and_send_task(ZB_REG_STEP_SEND_REGISTER_FINISH);
        }      
    } 
}
static void set_recv_post_device_info_response(dd_uint8_t response_id) {
    ZB_ziroom_get_device_info_response(response_id);
    dd_ack_rsp_context_t ack_rsp_context;
    DD_MEMSET(&ack_rsp_context, 0, sizeof(dd_ack_rsp_context_t));
    ack_rsp_context.ack_rsp_cb = zb_register_device_info_ack_rsp;
    ZB_ziroom_post_device_info(&ack_rsp_context);
   
}
#if 0
static void update_challenge_code(dd_uint8_t* challenge_code) {
    if (NULL == challenge_code)
        return;

    LOG_HIGHLIGHT("challenge code = %s", get_dm_challenge_code());

    if (get_dm_is_register_status()) // ���ڰ�����
    {
        if (get_zb_reg_step() > ZB_REG_STEP_GET_CHALLENGE_CODE) {
            return;
        }

        set_dm_challenge_code(challenge_code, DATA_SZ_CHALLENGE_RANDOM_KEY);

        step_retry_time = 0;
        set_next_register_step_and_send_task(ZB_REG_STEP_POST_AUTH_CODE);
    } else {
        // �ڷǰ󶨽׶�������յ���ս�룬��Ҫ����120s��ʱ�䴰��
        SW_TIMER_START(SW_TIMER_ID_REGISTER_PROCESS, REGISTER_PROCESS_TIMEOUT_MS);
        set_dm_challenge_code(challenge_code, DATA_SZ_CHALLENGE_RANDOM_KEY);
        SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_POST_AUTH_CODE);
    }
}

static void update_transkey(dd_uint8_t* transkey, dd_uint8_t* end_time) {
    if (NULL == transkey || NULL == end_time) {
        LOG_HIGHLIGHT("update_transkey : transkey or endtime is null");
        return;
    }

    LOG_HIGHLIGHT("update_transkey:transkey:%s end time:%d-%d-%d %d:%d:%d", transkey, end_time[0],
                  end_time[1], end_time[2], end_time[3], end_time[4], end_time[5]);

    if (get_dm_is_register_status()) // ���ڰ�����
    {
        if (get_zb_reg_step() > ZB_REG_STEP_POST_AUTH_CODE)
            return;

        set_dm_transkey(transkey, DATA_SZ_ENCRYPTED_TRANS_KEY);

        step_retry_time = 0;
        set_next_register_step_and_send_task(ZB_REG_STEP_SEND_REGISTER_DEVICE);
    } else {
        set_dm_transkey(transkey, DATA_SZ_ENCRYPTED_TRANS_KEY);
        LOG_HIGHLIGHT("update_transkey:transkey code = %s", get_dm_transkey());

        SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_SAVE_TRANSKEY);
    }
}

static void start_transkey_update_process(void) {
    if (get_dm_is_register_status()) // ���ڰ�����
        return;

    LOG("start request transkey update...");
    SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_GET_CHALLENGE_CODE);
}

/* ����������·����豸��Ϣ */
static void register_device(dd_uint8_t* uuid, dd_uint8_t* seed, dd_uint8_t* trans_key) {
    if (!get_dm_is_register_status()) // ���ڰ󶨹��̣�ֱ�ӷ���
        return;

    if ((uuid == NULL) || (seed == NULL)) {
        LOG_HIGHLIGHT("register_device : uuid or seed is NULL");
        return;
    }

    if (seed != NULL) {
        set_dm_pwdseed(seed, DATA_SZ_PWDSEED_KEY);
        LOG_HIGHLIGHT("register_device:seed = %s", get_dm_pwdseed());
    }

    if (get_zb_reg_step() > ZB_REG_STEP_SEND_REGISTER_DEVICE)
        return;

    // Save UUID
    set_dm_uuid(uuid, DATA_SZ_DEVICE_UUID_KEY);
    LOG_HIGHLIGHT("register_device:uuid = %s", get_dm_uuid());

    step_retry_time = 0;
    set_next_register_step_and_send_task(ZB_REG_STEP_SEND_REGISTER_REMOTE_SERVICE);
}

/* ����������·���unregister���� */
static void register_unregister(dd_uint32_t cmd_id) {
    dd_uint16_t data_length = sizeof(register_msg_context);
    dd_uint8_t* data = DD_MEM_MALLOC(data_length);
    APP_ERROR_CHECK(data == NULL);

    DD_MEMSET(data, 0, data_length);

    ((register_msg_context*)data)->cmd_id = cmd_id;
    SEND_TASK_TYPE_WITH_DATA(TASK_ID_REGISTER, MSG_REGISTER_UNREGISTER, data, data_length);
}

/* ����������·���bind���� */
static void register_bind(dd_uint32_t cmd_id) {
    dd_uint16_t data_length = sizeof(zb_trans_msg_context);
    dd_uint8_t* data = DD_MEM_MALLOC(data_length);
    APP_ERROR_CHECK(data == NULL);

    DD_MEMSET(data, 0, data_length);

    ((zb_trans_msg_context*)data)->cmd_id = cmd_id;
    ((zb_trans_msg_context*)data)->err_code = CODE_SUCCESS;

    SEND_TASK_TYPE_WITH_DATA(TASK_ID_ZB_TRANS, MSG_ZB_TRANS_SEND_BIND_SERVICE_RSP, data,
                             data_length);
}

/* ����������·���unbind���� */
static void register_unbind(dd_uint32_t cmd_id) {
    dd_uint16_t data_length = sizeof(zb_trans_msg_context);
    dd_uint8_t* data = DD_MEM_MALLOC(data_length);
    APP_ERROR_CHECK(data == NULL);

    DD_MEMSET(data, 0, data_length);

    ((zb_trans_msg_context*)data)->cmd_id = cmd_id;
    ((zb_trans_msg_context*)data)->err_code = CODE_SUCCESS;

    SEND_TASK_TYPE_WITH_DATA(TASK_ID_ZB_TRANS, MSG_ZB_TRANS_SEND_UNBIND_SERVICE_RSP, data,
                             data_length);
}

/* ����������·���seed�������� */
static void register_pwdseed(dd_uint32_t cmd_id, dd_uint8_t* seed, dd_uint8_t* trans_key,
                             dd_uint8_t* uuid) {
    if (seed == NULL || uuid == NULL || trans_key == NULL)
        return;

    if (0 != seed[0])
        set_dm_pwdseed(seed, DATA_SZ_PWDSEED_KEY);

    if (0 != uuid[0])
        set_dm_uuid(uuid, DATA_SZ_DEVICE_UUID_KEY);

    dd_uint16_t data_length = sizeof(register_msg_context);
    dd_uint8_t* data = DD_MEM_MALLOC(data_length);
    APP_ERROR_CHECK(data == NULL);

    DD_MEMSET(data, 0, data_length);
    ((register_msg_context*)data)->cmd_id = cmd_id;

    SEND_TASK_TYPE_WITH_DATA(TASK_ID_REGISTER, MSG_REGISTER_PWDSEED, data, data_length);
}

/* ����������·���serviceע����Ӧ */
static void register_remote_service(dd_bool_t success) {
    if (!get_dm_is_register_status()) // ���ڰ󶨹��̣�ֱ�ӷ���
        return;
    LOG_HIGHLIGHT("register_remote_service:success = %d", success);
    if (!success)
        return;

    if (get_zb_reg_step() > ZB_REG_STEP_SEND_REGISTER_REMOTE_SERVICE)
        return;

    SW_TIMER_STOP(SW_TIMER_ID_REGISTER_STEP);
    step_retry_time = 0;
    set_next_register_step_and_send_task(ZB_REG_STEP_SEND_REGISTER_FINISH);
}
#endif
/* ����ZBɨ��ɼ����������б��� */
static void scan_result(dd_uint16_t* list, dd_int32_t count) {
    // LOG_HIGHLIGHT("%s:%d", __func__, __LINE__);

    if ((!get_dm_is_register_status()) ||
        (get_zb_reg_step() != ZB_REG_STEP_GET_ZB_SCAN_LIST)) // ���ڰ󶨹��̣�ֱ�ӷ���
        return;

    if (0 == count) {
        LOG_HIGHLIGHT("No scan result!!!");
        return;
    }

    LOG_HIGHLIGHT("scan result count=%d", count);
    SW_TIMER_STOP(SW_TIMER_ID_REGISTER_STEP);

    // ����panid list
    cur_conn_panid_index = -1;
    cur_conn_panid_count = count;
    set_panid_list(list, count);

    set_next_register_step_and_send_task(ZB_REG_STEP_ZB_CONNECT);
}

/* �����������緵�ؽ�� */
static void connect_result(dd_bool_t is_connected) {
    LOG_HIGHLIGHT("connect_result=%d,dm_is_register_status=%d", is_connected,
                  get_dm_is_register_status());
    if (get_dm_is_register_status()) // ��ǰ���ڰ󶨽׶�
    {
        zb_register_step reg_step;
        
        if (!is_connected)
            return;

        reg_step = get_zb_reg_step();
        if (reg_step != ZB_REG_STEP_ZB_CONNECT && cur_conn_panid_index == -1 &&
            cur_conn_panid_count <= 0) {
            return;
        }
            
        DD_SLEEP_MS(1000);

        SW_TIMER_STOP(SW_TIMER_ID_REGISTER_STEP);

#ifdef ZIROOM_CUSTOM
        LOG("***connect_result:current bind step is %d", get_zb_reg_step());
        switch (reg_step) {
            case ZB_REG_STEP_ZB_CONNECT:
            case ZB_REG_STEP_WAIT_CLOUD_PUB: {
                 /* �쳣���������������set_next_register_step_and_send_task */
                set_register_step_and_send_task(ZB_REG_STEP_WAIT_CLOUD_PUB);
                break;
            }

            case ZB_REG_STEP_POST_PUB_KEY:
            case ZB_REG_STEP_WAIT_SHARE_KEY_SIGN: {
                set_register_step_and_send_task(ZB_REG_STEP_POST_PUB_KEY);
                break;
            }

            case ZB_REG_STEP_POST_SHARE_KEY_SIGN:
            case ZB_REG_STEP_WAIT_SIGN_RESULT: {
                set_register_step_and_send_task(ZB_REG_STEP_POST_SHARE_KEY_SIGN);
                break;
            }
            
            case ZB_REG_STEP_POST_REQUEST_TIMESTAMP:
            case ZB_REG_STEP_WAIT_GET_DEV_INFO: {
                set_register_step_and_send_task(ZB_REG_STEP_POST_REQUEST_TIMESTAMP);
                break;
            }

    		default: {
                LOG("***connect_result:rigster step abnormal:%d", reg_step);
                break;
            }
        } 
#else
        set_register_step_and_send_task(ZB_REG_STEP_POST_SN);
#endif
    } else // ��ǰ���ڷǰ󶨽׶�
    {
        if (!is_connected)
            return;

        zb_connect_handler();
    }
}

dd_int32_t generate_ecdsa_key_pair(dd_uint8_t prikey[DATA_SZ_ECC_PRIVATE_KEY],
                                   dd_uint8_t pubkey[DATA_SZ_ECC_PUBLIC_KEY]) {
    dd_int32_t ret = 0;
    dd_uint8_t public_key[DATA_SZ_ECC_PUBLIC_KEY] = {0};
    dd_uint8_t private_key[DATA_SZ_ECC_PRIVATE_KEY] = {0};

    // �����˽Կ
    rand_nums_generate(private_key, DATA_SZ_ECC_PRIVATE_KEY);

    // ���㹫Կ
    ret = uECC_compute_public_key(private_key, public_key, uECC_secp256r1());

    DD_MEMCPY(pubkey, public_key, DATA_SZ_ECC_PUBLIC_KEY);
    DD_MEMCPY(prikey, private_key, DATA_SZ_ECC_PRIVATE_KEY);

    return ret;
}

dd_int32_t ZB_ziroom_post_dev_pub(void) {
    dd_uint32_t ret = 0;
    dd_uint8_t temp_device_private_key[DATA_SZ_ECC_PRIVATE_KEY] __attribute__((aligned(4))) = {0};
    dd_uint8_t temp_public_key_cloud[DATA_SZ_ECC_PUBLIC_KEY] __attribute__((aligned(4))) = {0};
    dd_uint8_t temp_eshare_key[DATA_SZ_ECC_SHARE_KEY] __attribute__((aligned(4))) = {0};

    /* Ϊʹ���������Ͷ����ش�ʱ�ϱ������˹�Կ��ͬ,δ���ɹ���˽Կ�͹�����Կ����Ҫ�������� */
    if (local_key_is_created == DD_FALSE) {
        /* ͨ��ecc256�������˹�˽Կ */
        ret = generate_ecdsa_key_pair(ecc_private_key, ecc_public_key);
        if (ret == DD_FALSE) {
            LOG("***generate_ecdsa_key_pair fail");
            return -1;
        }

        /* ���ƶ˹�Կ������˽Կ����eShareKey */
        DD_MEMCPY(temp_public_key_cloud, ecc_public_key_cloud, DATA_SZ_ECC_PUBLIC_KEY);
        DD_MEMCPY(temp_device_private_key, ecc_private_key, DATA_SZ_ECC_PRIVATE_KEY);
        if (ecc_p256_shared_secret_compute(temp_device_private_key, temp_public_key_cloud,
                                           temp_eshare_key) < 0) {
            LOG("***ecc_p256_shared_secret_compute fail");
            register_dump_all_key();
            return -1;
        } else {
            /* ����eshare_key��ram��������ɣ��豣�汨flash */
            DD_MEMCPY(ecc_eshare_key, temp_eshare_key, DATA_SZ_ECC_SHARE_KEY);
            set_dm_sharekey(ecc_eshare_key, DATA_SZ_ECC_SHARE_KEY);
        }
        local_key_is_created = DD_TRUE;
    }

    set_key_type(KEY_BASE_SEED_ZIROOM); //���ݶ�����������,�ϱ���Կǰ��seed��������
    /* �ϱ����˹�Կ */
    ret =
        ziroom_protocol_data_send(CHANNEL_ZB_ID, ZIROOM_PROTOCOL_VERSION, ZB_ZIROOM_POST_PUB_KEY,
                                  ecc_public_key, DATA_SZ_ECC_PUBLIC_KEY, DD_TRUE, DD_FALSE, NULL);
    set_key_type(KEY_BASE_ZIROOM);  //���ݶ�����������,�ϱ���Կ����sharekey��������

    return ret;
}

dd_int32_t ZB_ziroom_post_share_key_sign(void) {
    dd_uint32_t ret = 0;
    dd_uint16_t crc_result = 0;
    dd_uint8_t data[2] = {0};

    /* ����CRC16(cloud_pub) */
    crc_result = bd_crc16(crc_result, ecc_public_key_cloud, DATA_SZ_ECC_PUBLIC_KEY);
    uint16_to_char_array(crc_result, data);
    /* ���͵��ƶ� */
    ret = ziroom_protocol_data_send(CHANNEL_ZB_ID, ZIROOM_PROTOCOL_VERSION,
                                    ZB_ZIROOM_POST_SHARE_KEY_SIGN, data, sizeof(data), DD_TRUE,
                                    DD_TRUE, NULL);

    return ret;
}

dd_int32_t ZB_ziroom_post_request_timestamp(void) {
    /* �����Ƿ���ҪУʱ������Ҫ�����ߣ��ȴ��ƶ˻�ȡ���汾��Ϣ�� */
    dd_uint32_t ret = 0;
    dd_uint8_t data_buf[10] = {0};
    dd_uint8_t len = 0;
    app_version_t app_version;
    dd_uint32_t time_val = 0;

    LOG("***ZB_ziroom_post_request_timestamp");
    app_version = st_get_app_version();               // app version
    time_val = get_curr_timestamp_int(DD_FALSE);      // linuxʱ���
    data_buf[len++] = get_battery_power_percentage(); // battery power
    data_buf[len++] = 0;                              // door state,��ʱ��0
    uint32_to_char_array(app_version, data_buf + len);
    len += sizeof(app_version);
    uint32_to_char_array(time_val, data_buf + len);
    len += sizeof(time_val);

    ret = ziroom_protocol_data_send(CHANNEL_ZB_ID, ZIROOM_PROTOCOL_VERSION,
                                    ZB_ZIROOM_REQUEST_TIMESTAMP, data_buf, len, DD_FALSE, DD_FALSE,
                                    NULL);

    return ret;
}

/*
 * ������ģ���ʼ��
 */
void register_task_init(void) {
    APP_TASK_OPEN(TASK_ID_REGISTER, APP_TASK_LOW_PRIORITY, register_task_on_msg, "register");

    ZB_L2_DATA_RECV_CB* l2_handler = get_zb_l2_data_handler();
    ZB_CMD_DATA_RECV_CB* cmd_handler = get_zb_cmd_data_handler();
    // ziroom
    l2_handler->recv_pub_key = set_pub_key_response;
    l2_handler->recv_share_key_sign = set_share_key_sign_response;
    l2_handler->recv_sign_result = set_recv_sign_result_response;
    l2_handler->update_timestamp = set_recv_update_timestamp_response;
    l2_handler->post_device_info = set_recv_post_device_info_response;

    cmd_handler->recv_scan_pandid_list = scan_result;
    cmd_handler->recv_connect_result = connect_result;

    // Create register timer
    SW_TIMER_CREATE(SW_TIMER_ID_REGISTER_STEP, SW_TIMER_TYPE_SINGLE, register_step_timer_handler);
    SW_TIMER_CREATE(SW_TIMER_ID_REGISTER_PROCESS, SW_TIMER_TYPE_SINGLE,
                    register_process_timeout_handler);
}

/*
 * �󶨹��̴�����ú����ǰ󶨹�������Ҫ�ĺ�����ÿ���󶨽׶ξ����ִ�ж��������������
 */
static void register_task_register_handler(register_msg_context* context) {
    dd_int32_t result = -1;
    dd_int32_t reg_step = get_zb_reg_step();
    SW_TIMER_STOP(SW_TIMER_ID_REGISTER_STEP);

    dd_int32_t delay_ms = DEFAULT_REGISTER_TIMEOUT_DELAY_MS;

    LOG_HIGHLIGHT("register step = %d", reg_step);

    DD_WDT_FEED();

    switch (reg_step) {
        case ZB_REG_STEP_START: {
            // �����豸��ǰ�ij�ʼ������
            //����ע���״̬�����洢��Flash
            set_dm_is_register_status(DD_TRUE);
            st_write_is_register_status(get_dm_is_register_status());

            step_retry_time = 0;
            scan_retry_time = 0;
            cur_conn_panid_index = 0;
            cur_conn_panid_count = 0;
            ZB_trans_reset();
            set_long_wakeup_mode(DD_TRUE);

            set_next_register_step_and_send_task(ZB_REG_STEP_GET_ZB_RESET);
            break;
        }

        case ZB_REG_STEP_GET_ZB_RESET: {
            step_retry_time = 0;
            scan_retry_time = 0;
            set_next_register_step_and_send_task(ZB_REG_STEP_GET_ZB_SCAN_LIST);
            break;
        }

        case ZB_REG_STEP_GET_ZB_SCAN_LIST: {
            // ZIGBEE_SCAN_WAIT_TIMEOUT_DELAY_MS �� 6 ��Ϊ3 s
            // SCAN_RETRY_TIME_RELOAD_CODE ��3�θ�Ϊ 6��
            //�����ý׶���ʱ�������
            //ͬʱȥ����ʱ����

            delay_ms = ZIGBEE_SCAN_WAIT_TIMEOUT_DELAY_MS;

            if (0 == scan_retry_time) {
                ZB_cmd_bind_YD_center_reset();
            }
#if 0
            //ɨ�賬ʱ���л�APP��3.0����ɨ��
            if (scan_retry_time % SCAN_RETRY_TIME_RELOAD_CODE == 0) {
                if (scan_retry_time == SCAN_RETRY_TIME_RELOAD_CODE) {
                    //����
                    register_reboot_reload_app();
                }
                //��һ�ο�ʼɨ��ʱ���õײ�Zigbee��λ
                if (CENTER_HW == get_zb_bind_mode()) {
                    ZB_cmd_bind_HW_center_reset();
                } else {
                    ZB_cmd_bind_YD_center_reset();
                }
                // �ڲ����ò���Ҫ��ʱ
                // DD_SLEEP_MS(2500);
            }
            dd_uint8_t* code = (dd_uint8_t*)get_dm_sn();
            code = code + 4; // install codeȡsn�ĵ�16λ
            ZB_cmd_set_install_code(code);
#endif
            //����ɨ�衣ɨ����ɺ��ص�scan_result();��ȡpandlist
            ZB_cmd_set_gw_type(gw_type_zb2); //������������
            ZB_cmd_request_scan();
            scan_retry_time++;

            break;
        }

        /*����ɨ���pandlist����������Zigbee���磬���ӳɹ���ص���connect_result();�������ӱ�־*/
        case ZB_REG_STEP_ZB_CONNECT: {
            if (cur_conn_panid_count > 0 && (++cur_conn_panid_index) < cur_conn_panid_count) {
                dd_uint16_t* panid_list = get_panid_list();
                if (panid_list[cur_conn_panid_index] != 0) {
                    set_dm_panid(panid_list[cur_conn_panid_index]);
                    register_zb_connect(cur_conn_panid_index);
                }
            }
            break;
        }
#if 0
        /*���ӳɹ��󣬿���postSN��post�ɹ����ص���post_sn_response();����enddevice_id*/
        case ZB_REG_STEP_POST_SN: {
            ZB_postSN_send();
            step_retry_time++;
            break;
        }

        /*postSN�ɹ���ʼ��ȡ��ս�롣��ȡ�ɹ���ص���update_challenge_code()�������ս��*/
        case ZB_REG_STEP_GET_CHALLENGE_CODE: {
            set_key_type(KEY_BASE_SN); // ʹ����Կ����1����

            ZB_get_challenge_code();
            step_retry_time++;
            break;
        }

        /*��ȡ��ս��ɹ����ϱ���֤���ȡ ͨѶ��Կtranskey����ȡ�ɹ���ص���update_transkey()*/
        case ZB_REG_STEP_POST_AUTH_CODE: {
            update_key_base_rootkey(get_dm_rootkey(), DEVICE_DATA_LEN_ROOT_KEY,
                                    get_dm_challenge_code(), DATA_SZ_CHALLENGE_RANDOM_KEY);
            set_key_type(KEY_BASE_ROOTKEY); // ʹ����Կ����2����

            dd_uint8_t auth_code[4] = {0};
            uint32_to_char_array(
                generate_auth_code((dd_uint8_t*)get_dm_challenge_code(),
                                   (dd_uint8_t*)get_dm_rootkey(), (dd_uint8_t*)get_dm_sn(),
                                   (dd_uint8_t*)get_dm_mac()),
                auth_code);
            ZB_post_auth_code(auth_code);
            step_retry_time++;
            break;
        }

        /*��ȡtranskey���ϱ��豸ע����Ϣ,ע��ɹ����ص���register_device(),��ȡ����������seed��uuid*/
        case ZB_REG_STEP_SEND_REGISTER_DEVICE: {
#if (SECURITY_USE_ROOT_KEY == 1)
            update_key_base_transkey_bind(get_dm_transkey(), DEVICE_DATA_LEN_TRANS_KEY, get_dm_sn(),
                                          SN_SIZE);
            set_key_type(KEY_BASE_TRANSKEY_BIND); // ʹ����Կ����3����
#else
            set_key_type(KEY_BASE_SN); // ʹ����Կ����1����
#endif

            ZB_registerDevice_send();
            step_retry_time++;
            break;
        }

        /*ע��ɹ���ע��service�����������ɹ����ص���register_remote_service()*/
        case ZB_REG_STEP_SEND_REGISTER_REMOTE_SERVICE: {
#if (SECURITY_USE_ROOT_KEY == 0)
            update_key_base_seed(get_dm_pwdseed(), DATA_SZ_PWDSEED_KEY, get_dm_uuid(),
                                 DATA_SZ_DEVICE_UUID_KEY);
            set_key_type(KEY_BASE_SEED); // ʹ�û���seed���ɵ�xor_key����
#endif

            ZB_registerRemoteService_send();
            step_retry_time++;
            break;
        }

        /*ע��Service�ɹ���ͬ������*/
        case ZB_REG_STEP_SYNC_PASSWORD_PRE: {
            create_password_sync_data();
            step_retry_time = 0;
            set_next_register_step_and_send_task(ZB_REG_STEP_SYNC_PASSWORD_ID);
            break;
        }

        case ZB_REG_STEP_SYNC_PASSWORD_ID: {
            dd_ack_rsp_context_t ack_rsp_context;
            DD_MEMSET(&ack_rsp_context, 0, sizeof(dd_ack_rsp_context_t));
            ack_rsp_context.ack_rsp_cb = register_password_id_sync_ack_rsp;
            delay_ms = PASSWORD_SYNC_DELAY_MS;

            // ������0ʱ��ʾû��ID���ݣ���ֱ������ͬ���������ݲ���,���ע�������
            if (0 == register_zb_sync_password_id(&ack_rsp_context)) {
                LOG_HIGHLIGHT("ZB_REG_STEP_SYNC_PASSWORD_ID:no password,go to register finish");
                set_register_step_and_send_task(ZB_REG_STEP_SEND_REGISTER_FINISH);
            }
            break;
        }

        case ZB_REG_STEP_SYNC_PASSWORD_DATA: {
            password_node node_list[MAX_PWD_SYNC_SEND_COUNT];
            dd_int32_t node_len = 0;

            DD_MEMSET(node_list, 0, sizeof(node_list));
            node_len = get_next_pwd_sync_node_list(node_list);

            if (node_len > 0) {
                dd_ack_rsp_context_t ack_rsp_context;
                DD_MEMSET(&ack_rsp_context, 0, sizeof(dd_ack_rsp_context_t));
                ack_rsp_context.ack_rsp_cb = register_password_data_sync_ack_rsp;
                ZB_Password_Sync_send((dd_uint8_t*)node_list, node_len, &ack_rsp_context);
                delay_ms = PASSWORD_SYNC_DELAY_MS;
            } else {
                set_next_register_step_and_send_task(ZB_REG_STEP_SEND_REGISTER_FINISH);
                step_retry_time = 0;
            }

            break;
        }
#endif
        /********************oyh:ziroom*********************/
        case ZB_REG_STEP_WAIT_CLOUD_PUB: {
            /* ���ɻ���seed�����key */
            update_key_base_seed_ziroom(get_dm_pwdseed(), 16, LOCKIN_ZIROOM_SECRET_SALT, 16);
            /* key_type�л�Ϊseed,�ϱ����˹�Կ����Ϊsharekey */
            set_key_type(KEY_BASE_SEED_ZIROOM);
            break;
        }
        case ZB_REG_STEP_POST_PUB_KEY: {
            if (ZB_ziroom_post_dev_pub() == DD_TRUE) {
                /* ������һ�󶨲��� */
                set_register_step_and_send_task(ZB_REG_STEP_WAIT_SHARE_KEY_SIGN);
            } else {
                set_zb_reg_step(ZB_REG_STEP_FAIL);
            }

            break;
        }
        case ZB_REG_STEP_WAIT_SHARE_KEY_SIGN: {
            /* ���ɻ���eShareKey�����key */
            update_key_base_sharekey_ziroom(get_dm_sharekey(), 16, get_dm_sharekey() + 16, 16);
            /* �����ƶ��·���Կ��ǩ�����轫key_type�л�ΪeShareKey,�������̶�ʹ�ø�type */
            set_key_type(KEY_BASE_ZIROOM);

            break;
        }
        case ZB_REG_STEP_POST_SHARE_KEY_SIGN: {
            if (ZB_ziroom_post_share_key_sign() == DD_TRUE) {
                /* ������һ�󶨲��� */
                set_zb_reg_step(ZB_REG_STEP_WAIT_SIGN_RESULT);
            } else {
                set_zb_reg_step(ZB_REG_STEP_FAIL);
            }
            break;
        }

        case ZB_REG_STEP_POST_REQUEST_TIMESTAMP: {
            /* ��һ�׶��ƶ˿��ܷ�Уʱָ�Ҳ����ֱ�ӷ���ȡ����Ϣ��ָ�� */
            /* ����Уʱָ����Բ����ڰ������У�����ָ��ֱ��Уʱ���� */
            /* ������һ�׶��ǵȴ���ȡ������Ϣ */
            if (ZB_ziroom_post_request_timestamp() == DD_TRUE) {
                /* ������һ�󶨲��� */
                set_zb_reg_step(ZB_REG_STEP_WAIT_GET_DEV_INFO);
            } else {
                set_zb_reg_step(ZB_REG_STEP_FAIL);
            }
            break;
        }

        case ZB_REG_STEP_SEND_REGISTER_FINISH: {
            //   result = ZB_registerFinish_Send();
            result = 0;
            LOG_HIGHLIGHT("Send register finish success,ret = %d", result);
            if (result == 0) {
                LOG_HIGHLIGHT("revice register finish ack!");
                SW_TIMER_STOP(SW_TIMER_ID_REGISTER_PROCESS);
                //����󶨹����е�������Ϣ
                SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_SAVE_INFO);
            } else {
                step_retry_time++;
            }

            break;
        }

        case ZB_REG_STEP_FINISH: {
            SW_TIMER_STOP(SW_TIMER_ID_REGISTER_PROCESS);
            reset_zb_reg_step();

            // ����ע���־
            set_dm_is_register(DD_TRUE);
            st_write_is_register(get_dm_is_register());

            // ����ע��״̬��־
            set_dm_is_register_status(DD_FALSE);
            st_write_is_register_status(get_dm_is_register_status());

            //��������󶨱��
            set_dm_is_ble_register(DD_FALSE);

            /* ���flash�еĹ�Կ */
            clear_flash_public_key_cloud();

            //�����ʱ��������
            st_reset_tmp_pwdseed();
            set_dm_tmp_pwdseed_enable_flag(DD_FALSE);

            //�洢��ģʽ
            storage_zb_bind_mode_to_flash();

            //��λ�󶨿�ʼ��App����
            st_reset_register_start_app_type();

            if (NULL != register_success_cb)
                register_success_cb();
            break;
        }

        case ZB_REG_STEP_FAIL: {
            LOG_HIGHLIGHT("register_timeout,ZIGBEE FOR REGISTER FAIL");
            SW_TIMER_STOP(SW_TIMER_ID_REGISTER_PROCESS);
            reset_zb_reg_step();
            //��λ�󶨿�ʼ��App����
            st_reset_register_start_app_type();

            if (NULL != register_fail_cb)
                register_fail_cb();

            break;
        }

        default: {
            reset_zb_reg_step(); // reset zb register step
            break;
        }
    }

        // ÿ���󶨽׶ζ���Ҫ����restart
        // timer,�ڳ�ʱ��������и��ݵ�ǰ�׶��ж��Ƿ���Ҫ����ǰһ��������߽����󶨹���
    if (get_zb_reg_step() != ZB_REG_STEP_NONE)
        SW_TIMER_START(SW_TIMER_ID_REGISTER_STEP, delay_ms);
}

/* ����MSG_REGISTER_SAVE_INFO���� */
static void register_task_save_info_handler(register_msg_context* context) {
    LOG("REGISTER SAVE INFO");
    SW_TIMER_STOP(SW_TIMER_ID_REGISTER_PROCESS);
    dd_uint16_t enddevice_id = get_dm_enddevice_id();

    set_dm_panid(
        get_zb_panid()); // �������ڰ󶨵�ʱ����ʹ��MAC��ַת����panid���ӣ��������ӳɹ�����Ҫ�������panidΪ��ʵ��panid

    dd_uint16_t panid = get_dm_panid(); //��չpandID

    // Save enddevicd_id/panid/uuid
    st_write_enddevice_id(&enddevice_id);

    if (panid != 0)
        st_write_zb_panid(panid);

    uint16_t actualPanid = get_zb_panid(); // emberAfGetPanId(); //��ʵpadnId
    if (actualPanid != 0) {
        st_write_zb_actual_panid(actualPanid);
    }
    LOG("register_task_save_info_handler:actualPanid=0x%0x,extendPandId=0x%0x", actualPanid, panid);
    st_write_uuid((dd_uint8_t*)get_dm_uuid());
    // st_write_pwdseed((dd_uint8_t*)get_dm_pwdseed());
    //  st_write_trans_key((dd_uint8_t*)get_dm_transkey());
    st_write_sharekey(get_dm_sharekey());

    set_next_register_step_and_send_task(ZB_REG_STEP_FINISH);
}
#if 0
/* ����MSG_REGISTER_CHECK_PWDSEED���� */
static void register_task_check_pwdseed(register_msg_context* context) {
    const dd_uint8_t* seed = get_dm_pwdseed();
    const dd_uint8_t* uuid = get_dm_uuid();

    // ��seed����uuid�쳣ʱ��Ҫ��������seed
    if (get_dm_is_register() &&
        (ST_CHECK_DATA_IS_NULL_AND_INVALID(seed) || ST_CHECK_DATA_IS_NULL_AND_INVALID(uuid))) {
        set_key_type(KEY_BASE_SN); // Set encrypt based SN

        ZB_RetryPwdSeed_TransKey_send(RETRY_GET_PWDSEED_KEY_2C);
    }
}

/* ����MSG_REGISTER_CHECK_TRANSKEY���� */
static void register_task_check_transkey(register_msg_context* context) {
    dd_uint8_t trans_key[DATA_SZ_ENCRYPTED_TRANS_KEY + 1] = {
        0,
    };

    st_read_trans_key(trans_key);

    if (ST_CHECK_DATA_IS_NULL_AND_INVALID(trans_key)) {
        start_transkey_update_process();
    }
}

/* ����MSG_REGISTER_PWDSEED���� */
static void register_task_update_seed(register_msg_context* context) {
    if (context == NULL)
        return;

    const dd_uint8_t* seed = get_dm_pwdseed();
    const dd_uint8_t* uuid = get_dm_uuid();
    const dd_uint8_t* trans_key = get_dm_transkey();

    LOG("RETRY PWDSEED=%s UUID=%s TRANS_KEY=%s", seed, uuid, trans_key);
    st_write_pwdseed((dd_uint8_t*)seed);
    st_write_uuid((dd_uint8_t*)uuid);

    // ֻ��UUID��SEED������ʱ���л�
#if (SECURITY_USE_ROOT_KEY == 0)
    if ((!ST_CHECK_DATA_IS_NULL_AND_INVALID(seed)) && (!ST_CHECK_DATA_IS_NULL_AND_INVALID(uuid))) {
        update_key_base_seed(seed, DATA_SZ_PWDSEED_KEY, get_dm_uuid(), DATA_SZ_DEVICE_UUID_KEY);
        set_key_type(KEY_BASE_SEED); // Set encrypt type based SEED
    }
#endif

#if (RANDOM_PWD_ENABLE == 1) // ���¶�̬����
    SEND_TASK_TYPE(TASK_ID_PASSWORD, MSG_PASSWORD_GEN_RANDOM);
#endif

#if (ONE_TIME_RANDOM_PWD_ENABLE == 1) // ����һ���Զ�̬����
    SEND_TASK_TYPE(TASK_ID_PASSWORD, MSG_PASSWORD_GEN_ONE_TIME_RANDOM);
#endif

    dd_uint16_t data_length = sizeof(zb_trans_msg_context);
    dd_uint8_t* data = DD_MEM_MALLOC(data_length);
    APP_ERROR_CHECK(data == NULL);

    DD_MEMSET(data, 0, data_length);

    ((zb_trans_msg_context*)data)->cmd_id = context->cmd_id;
    ((zb_trans_msg_context*)data)->err_code = CODE_SUCCESS;

    SEND_TASK_TYPE_WITH_DATA(TASK_ID_ZB_TRANS, MSG_ZB_TRANS_SEND_PWDSEED_SERVICE_RSP, data,
                             data_length);

    // �����ϱ��汾����Ϣ
    device_info_send_process();
}

/* ����MSG_REGISTER_TRANS_KEY���� */
static void register_task_update_transkey(register_msg_context* context) {
    if (context == NULL)
        return;

    const dd_uint8_t* trans_key = get_dm_transkey();

    LOG("MSG REGISTER TRANSKEY = %s", trans_key);
    st_write_trans_key((dd_uint8_t*)trans_key);

    dd_uint16_t data_length = sizeof(zb_trans_msg_context);
    dd_uint8_t* data = DD_MEM_MALLOC(data_length);
    APP_ERROR_CHECK(data == NULL);

    DD_MEMSET(data, 0, data_length);

    ((zb_trans_msg_context*)data)->cmd_id = context->cmd_id;
    ((zb_trans_msg_context*)data)->err_code = CODE_SUCCESS;

    SEND_TASK_TYPE_WITH_DATA(TASK_ID_ZB_TRANS, MSG_ZB_TRANS_SEND_BLE_TRANS_KEY_SERVICE_RSP, data,
                             data_length);
}
#endif
/* ����MSG_REGISTER_BUTTON_START���� */
static void register_task_button_start(register_msg_context* context) {
    //ֹͣack��ʱ��ʱ��
    stop_rsp_check_timer();

    if ((CENTER_HW == get_zb_bind_mode()) &&
        (ZB_REG_STEP_PREPARE_BIND_HW_CENTER == get_zb_reg_step())) {
        SW_TIMER_STOP(SW_TIMER_ID_REGISTER_STEP);
    }
    /* ���flash�еĹ�Կ */
    clear_flash_public_key_cloud();
        
    device_register_prepare_logic_async();
    st_reset_register_time_used_millisecond();

    register_success_cb = device_register_zb_success_cb;
    register_fail_cb = device_register_zb_fail_cb;
    register_start_second_counter = get_second_wallclock();

    set_zb_reg_step(ZB_REG_STEP_START);

    //���õ�ǰ��ʼע���App����
    st_write_register_start_app_type(get_current_runing_type());

    //����������ܼ�����
    st_reset_ziroom_cipher_counter();

#ifdef YD_BLE_APP_SUPPORT
    //�󶨿�ʼ�ȶϿ�����
    SEND_TASK_TYPE(TASK_ID_BLE_TRANS, MSG_BLE_TRANS_DISCONNECT);
#endif
    SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);

    SW_TIMER_START(SW_TIMER_ID_REGISTER_PROCESS, REGISTER_PROCESS_TIMEOUT_MS);
}
#if 0
/* ����MSG_REGISTER_EXPAND_CMD_START���� */
static void register_task_expand_cmd_start(register_msg_context* context) {
    if (ZB_REG_STEP_NONE == get_zb_reg_step()) // �ȴ����ü�������Ϊ���ذ�����
    {
        set_zb_reg_step(ZB_REG_STEP_PREPARE_BIND_HW_CENTER);

        set_zb_bind_mode(CENTER_HW);
        set_zb_bind_mtu(ZB_L0_MTU_HW);

        SW_TIMER_START(SW_TIMER_ID_REGISTER_STEP, REGISTER_PREPARE_BIND_HW_CENTER_TIMEOUT_MS);
    }
}
#endif
/* MSG_REGISTER_RESTART_START */
static void register_task_restart_start(register_msg_context* context) {
    dd_uint8_t* public_key_cloud = NULL;

    if (NULL == context)
        return;

    //������쳣��λ ֱ�ӱ���ʧ�ܽ���
    if (NORMAL_RESET != context->power_on_cause && NV_RECOVER_RESET != context->power_on_cause) {
        reset_zb_reg_step();
        device_register_zb_fail_cb();
        return;
    }

    LOG("=======%s:%d======", __func__, __LINE__);

    if ((CENTER_HW == get_zb_bind_mode()) &&
        (ZB_REG_STEP_PREPARE_BIND_HW_CENTER == get_zb_reg_step())) {
        SW_TIMER_STOP(SW_TIMER_ID_REGISTER_STEP);
    }

    device_register_prepare_logic_async();

    register_success_cb = device_register_zb_success_cb;
    register_fail_cb = device_register_zb_fail_cb;
    register_start_second_counter = get_second_wallclock();

    if (flash_public_key_cloud_is_valid() == DD_TRUE) {
        step_retry_time = 0;
        
        /* �յ��ƶ˹�Կ������ָ���,��Ҫ��flash�еĹ�Կ����ȫ�ֱ��� */
        public_key_cloud = get_dm_public_key_cloud();
        DD_MEMCPY(ecc_public_key_cloud, public_key_cloud, DATA_SZ_ECC_PUBLIC_KEY);

        update_key_base_seed_ziroom(get_dm_pwdseed(), 16, LOCKIN_ZIROOM_SECRET_SALT, 16);
        /* key_type�л�Ϊseed,�ϱ����˹�Կ����Ϊsharekey */
        set_key_type(KEY_BASE_SEED_ZIROOM);
        set_zb_reg_step(ZB_REG_STEP_POST_PUB_KEY);
    } else {
        set_zb_reg_step(ZB_REG_STEP_START);
    }

#ifdef YD_BLE_APP_SUPPORT
    //�󶨿�ʼ�ȶϿ�����
    SEND_TASK_TYPE(TASK_ID_BLE_TRANS, MSG_BLE_TRANS_DISCONNECT);
#endif
    SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);

    dd_uint32_t millisecond = st_read_register_time_used_millisecond();
    LOG_HIGHLIGHT("register_task_restart_start,millisecond:%u",millisecond);
    if (millisecond >= REGISTER_PROCESS_TIMEOUT_MS) {
        set_zb_reg_step(ZB_REG_STEP_FAIL);
        SEND_TASK_TYPE(TASK_ID_REGISTER, MSG_REGISTER_REGISTER);
    } else {
        SW_TIMER_START(SW_TIMER_ID_REGISTER_PROCESS, (REGISTER_PROCESS_TIMEOUT_MS - millisecond));
    }
}
#if 0
/* ����MSG_REGISTER_GET_CHALLENGE_CODE���� */
static void register_task_get_challenge_code(register_msg_context* context) {
    set_key_type(KEY_BASE_SN); // Set encrypt type based SN
    ZB_get_challenge_code();
}

/* ����MSG_REGISTER_POST_AUTH_CODE���� */
static void register_task_post_auth_code(register_msg_context* context) {
    update_key_base_rootkey(get_dm_rootkey(), DEVICE_DATA_LEN_ROOT_KEY, get_dm_challenge_code(),
                            DATA_SZ_CHALLENGE_RANDOM_KEY);
    set_key_type(KEY_BASE_ROOTKEY); // Set encrypt type based SN

    dd_uint8_t auth_code[4] = {0};
    uint32_to_char_array(
        generate_auth_code((dd_uint8_t*)get_dm_challenge_code(), (dd_uint8_t*)get_dm_rootkey(),
                           (dd_uint8_t*)get_dm_sn(), (dd_uint8_t*)get_dm_mac()),
        auth_code);
    ZB_post_auth_code(auth_code);
}

/* ����MSG_REGISTER_SAVE_TRANSKEY���� */
static void register_task_save_transkey(register_msg_context* context) {
    reset_dm_challenge_code();
    st_write_trans_key((dd_uint8_t*)get_dm_transkey());
    update_key_base_transkey_uuid(get_dm_transkey(), DEVICE_DATA_LEN_TRANS_KEY, get_dm_uuid(),
                                  ST_UUID_SIZE);
    set_key_type(KEY_BASE_TRANSKEY_UUID);
}
#endif
/* ��ģ������ִ�� */
void register_task_on_msg(tm_msg* msg, dd_uint16_t msg_size) {
    register_msg_context* context = NULL;
    if (msg->data != NULL) {
        context = (register_msg_context*)(msg->data);
    }

    switch (msg->type) {
        case MSG_REGISTER_REGISTER: {
            register_task_register_handler(context);
            break;
        }

        case MSG_REGISTER_SAVE_INFO: {
            register_task_save_info_handler(context);
            break;
        }
#if 0
        case MSG_REGISTER_CHECK_PWDSEED: {
            register_task_check_pwdseed(context);
            break;
        }

        case MSG_REGISTER_CHECK_TRANSKEY: {
            register_task_check_transkey(context);
            break;
        }

        case MSG_REGISTER_PWDSEED: {
            register_task_update_seed(context);
            break;
        }

        case MSG_REGISTER_TRANS_KEY: {
            register_task_update_transkey(context);
            break;
        }
#endif
        case MSG_REGISTER_BUTTON_START: {
            register_task_button_start(context);
            break;
        }
#if 0
        case MSG_REGISTER_EXPAND_CMD_START: {
            register_task_expand_cmd_start(context);
            break;
        }
#endif
        case MSG_REGISTER_RESTART_START: {
            register_task_restart_start(context);
            break;
        }
#if 0
        case MSG_REGISTER_GET_CHALLENGE_CODE: {
            register_task_get_challenge_code(context);
            break;
        }

        case MSG_REGISTER_POST_AUTH_CODE: {
            register_task_post_auth_code(context);
            break;
        }

        case MSG_REGISTER_SAVE_TRANSKEY: {
            register_task_save_transkey(context);
            break;
        }
#endif
        default:
            break;
    }
}

  • Hi Reed,

    Both register_task.c and ZB_REG_STEP_ZB_CONNECT are not provided by the TI Z-Stack solution, thus I assume a third-party solution is involved.  The register_task.c file header mentions Confidential and Proprietary information, are you certain this is allowed to be shared on a public forum?

    zstack_DevState_END_DEVICE_UNAUTH / DEV_END_DEVICE_UNAUTH means that the device has joined the Zigbee network but is not yet authenticated by the Trust Center.  The ZC TC does not provide the correct NWK key, or if it is not received by the ZED, within MAX_DEVICE_UNAUTH_TIMEOUT then the device will reset.  In the "connect ok.cubx" file I am not able to determine the data packets after association as they appear to be illegible.  The "UnableToConnect.cubx" shows the NWK key being transported by the ZC, and ACKd by the ZED, but with no further communication.  This could imply that it was trying to rejoin a Zigbee network and did not expect the NWK key delivered.

    I recommend that you erase all device memory and/or factory reset before reprogramming, and confirm the output TX power for each device.  Also comment on whether the one device always performs well whereas the other two prototypes do not when using the exact same binary image and hardware.  Test for a freshly formed Zigbee network as well.

    Regards,
    Ryan

  • During the process of networking, the device received the NWK key issued by the server and experienced a crash issue. I would like to inquire about troubleshooting methods;
    1. Is there any tool to investigate the cause of the dump that triggers the watchdog reset

  • Based on the description provided, ZDApp_ResetTimerStart is expiring on MAX_DEVICE_UNAUTH_TIMEOUT and calling the ZDO_DEVICE_RESET event to perform a SysCtrlSystemReset.  This is not a "watchdog" in the sense of the hardware peripheral, it is simply a system reset because association has begun but the network key is not received or processed correctly.  You can debug ZDApp_ProcessSecMsg -> ZDSecMgrTransportKeyInd, or plug in UART/Printlogs to determine why it is not calling ZDSecMgrAuthNwkKey to authenticate the device.  Please provide additional debug insight based on the description I have provided.

    Regards,
    Ryan