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.

LP-EM-CC2340R53:Use serial port 2 for asynchronous character reception, while running other business logic simultaneously.

Part Number: LP-EM-CC2340R53
Other Parts Discussed in Thread: SYSCONFIG, CC2340R5

Tool/software:

Hi

The running example is a door lock.

After adding the initialization of logs to my initialization process, it just keeps getting stuck in the serial port input and output process. However, the underlying logic for the other Zigbee devices is not functioning.
The desired effect is that when there is input on the serial port, the characters should be received and corresponding logical processing should be carried out. And it is also output via the serial port. Then the logic of Zigbee is not affected either.
How should it be modified?

/* door_lock.c */
#include "uart2callback.h"

MAIN()
{
  ARGV_UNUSED;

  /* Global ZBOSS initialization */
  ZB_INIT("door_lock");

  logThread(NULL); // 日志初始化
  uart2_printf("zboss_start\r\n");
  ...
}


/* uart2callback.c */

#include <stdint.h>
#include <stddef.h>

/* POSIX Header files */
#include <semaphore.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART2.h>

/* Driver configuration */
#include "ti_drivers_config.h"
#include <stdarg.h>
#define  LOG_ENALBE

static sem_t sem;
static volatile size_t numBytesRead;

static UART2_Handle uart;

void uart2_printf(char *buffer);

/*
 *  ======== callbackFxn ========
 */
void callbackFxn(UART2_Handle handle, void *buffer, size_t count, void *userArg, int_fast16_t status)
{
     if (status != UART2_STATUS_SUCCESS)
    {
        /* RX error occured in UART2_read() */
        while (1) {}
    }

    numBytesRead = count;
    sem_post(&sem);
}

/*
 *  ======== logThread ========
 */
void *logThread(void *arg0)
{
    char input;
    const char echoPrompt[] = "Echoing characters:\r\n";
    UART2_Handle uart;
    UART2_Params uartParams;
    int32_t semStatus;
    uint32_t status = UART2_STATUS_SUCCESS;

    /* Call driver init functions */
    //GPIO_init();

    /* Configure the LED pin */
    //GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    /* Create semaphore */
    semStatus = sem_init(&sem, 0, 0);

    if (semStatus != 0)
    {
        /* Error creating semaphore */
        while (1) {}
    }

    /* Create a UART in CALLBACK read mode */
    UART2_Params_init(&uartParams);
    uartParams.readMode     = UART2_Mode_CALLBACK;
    uartParams.readCallback = callbackFxn;
    uartParams.baudRate     = 115200;

    uart = UART2_open(CONFIG_UART2_0, &uartParams);

    if (uart == NULL)
    {
        /* UART2_open() failed */
        while (1) {}
    }

    /* Turn on user LED to indicate successful initialization */
    //GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

    /* Pass NULL for bytesWritten since it's not used in this example */
    UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);

    /* Loop forever echoing */
    while (1)
    {
        numBytesRead = 0;

        /* Pass NULL for bytesRead since it's not used in this example */
        status = UART2_read(uart, &input, 1, NULL);

        if (status != UART2_STATUS_SUCCESS)
        {
            /* UART2_read() failed */
            while (1) {}
        }

        /* Do not write until read callback executes */
        sem_wait(&sem);

        if (numBytesRead > 0)
        {
            status = UART2_write(uart, &input, 1, NULL);

            if (status != UART2_STATUS_SUCCESS)
            {
                /* UART2_write() failed */
                while (1) {}
            }
        }
    }
}

void uart2_printf(char *buffer)
{
#ifdef LOG_ENALBE
        int len=strlen(buffer);
        if(uart)
        {
                UART2_write(uart,buffer,len,NULL);
        }
#endif
}

Best Regards, 
yongjian

  • hi 

    SQLite format 3@  
    .j�
    ��j��
    �
    �
    �{�EtableAddressesAddresses
    CREATE TABLE [Addresses] ([Id] Integer PRIMARY KEY AUTOINCREMENT, [Long] TEXT, [Short] TEXT)j�7tableKeysKeys	CREATE TABLE [Keys] ([Id] Integer PRIMARY KEY AUTOINCREMENT, [Key] BLOB, [Type] TEXT)P++Ytablesqlite_sequencesqlite_sequenceCREATE TABLE sqlite_sequence(name,seq)��UtablePacketsPacketsCREATE TABLE [Packets] ([Id] Integer PRIMARY KEY AUTOINCREMENT, [Raw] BLOB, [Stack] INTEGER, [Channel] INTEGER, [Timestamp] REAL, [TimeDelta] REAL, [LQI] INTEGER, [RSSI] INTEGER, [Comment] TEXT, [DeviceId] INTEGER, [OK] INTEGER)��{tableDevicesDevicesCREATE TABLE [Devices] ([Id] Integer PRIMARY KEY, [Alias] TEXT, [Description] TEXT, [Stack] INTEGER, [Channel] INTEGER)[�	tableMetadataMetadataCREATE TABLE [Metadata] ([Key] Text PRIMARY KEY, [Value] TEXT)/Cindexsqlite_autoindex_Metadata_1Metadata
    ����y7�2!WSystemInfoMicrosoft Windows NT 10.0.26100.0 [8]	
    Locale'SavedWithUbiqua/2.5.68@!sComputerId6EAFEBF52640E9CFBF-3F442428058D9550DD66F09F200397A6!FileFormat2)ITimeZone(UTC+08:00) 中国标准时间/SavedAt1750227111.598998-SSavedByyong wang <pyj3290888673@gmail.com>
    ���������!SystemInfo
    Locale
    SavedWith!ComputerId!FileFormatTimeZoneSavedAt
    	SavedBy
    ��2875628756���~R
    �
    �
    c
    ��R+��;
    �
    �
    *
    	|	U��L%��5��"��v��f?��2�{!�m�R5p
    		A�Dގ��	���q6K(�q6K��r�M���+�A���@'�E�&����X4|
    		A�Cގ������N�q6K(�q6K���
    ��q�,�xTA��g?������X3|
    		A��ގ��������N�q6K(N�q6K�9D,��[7�_�
    ��+A��N�?��Lv����X2|
    		A�Bގ������N�q6K(�q6K�mG��	�`e�A���B?���^�����X1|
    		A��ގ��������N�q6K(N�q6K)��Z��d�&����h1A���?�ڜ�(Z���%0
    		��A���?e~�E�]��g/
    �
    		a��ގ��H���q6KN�q6K(N�q6K���Y��qԞ%7����д-Z͛A���?����I���%.
    		A5�A��g'?j��!���{-
    �@
    		a�Aގ��H��N�q6K�q6K(�q6K��n.x"7�D����l�c?�IU�y0����4.|�	-���A��1�?u"���/���%,
    		@��A���#?e~�E�]��g+
    �
    		a�@ގ��H��N�q6K�q6K(�q6K��ׅR����1�O-�I+�|K؝A���%?����3���%*
    		�{�A����?f�\��w6��k)
    � 
    		a��ގ��H���q6KN�q6K(N�q6K��>��̺�#5%+&���'d2��A��|�?�!��}���%(
    		>EmA��
    4�?jy�ɟ���z'
    �>
    		a�>ގ��H��N�q6K�q6K1a0�q6KO<��|�0�{�S#?����I�	ޣ^Y;�ڙA��	��?�:�}��%&
    		�eA����?b���IӉ��\%
    �
    		a��ގ��H���q6KN�q6K�N�q6K2_�pm\��A����?}�̒j��%$
    		=�_A��/?g��9����o#
    �(
    		a�=ގ��H��N�q6K�q6K`%N�q6Kq_ �q6K���X�ԶiE���ȵA����?�/��g��%"
    		<WNA��fk?`@��>!��R!p
    		a�<ގ��H��N�q6K�q6K^	N�q6K��mA��E�?��I�����% 
    		��WA���]W?g�|�&���m
    �$
    		a��ގ��H��	�q6KN�q6K�#N�q6KQ�N�q6K�d�`�rhpcpVk�KSx�A���/4?��<�P;���%
    		�FA��Сb?a�g�Lf��X|
    		a��ގ��H���q6KN�q6K�N�q6K@�\��A���}�?�_���~��%
    		;�:A�����?m\1Y>_��ہ
    �T
    		a�;ގ��H��N�q6K�q6K];N�q6K@@�\'�q6K<��I,��:���n�
    ~MX��pL�a��^f!A�����?_�,+����%
    		:a+A���d?a�g�Lf��X|
    		a�:ގ��H��N�q6K�q6K[N�q6K@�9�A���@y?��.H���%
    		��2A��gB?mz���ہ
    �R
    		a��ގ��H���q6KN�q6K�:N�q6K@@�'N�q6KT��5�B��$��RF,�t���iΫNk׀�p�CR�A��g�?�#�1�S��%
    		9�A��4�?a�g�Lf��X|
    		a�9ގ��H��N�q6K�q6KZN�q6KE��5A��4��?�z�����%
    		�!#A��3�P?e~�E�]��g
    �
    		a��ގ��H���q6KN�q6K�N�q6K@E��	�N�q6K̒A��3�R?��j�@-��%
    		��A��26�?a�g�Lf��X|
    		a��ގ��H���q6KN�q6K�N�q6KEXO�A��2E?��r%�I���%
    		8sA��0w-?g�|�&���m
    �$
    		a�8ގ��H��N�q6K�q6KY#N�q6K@EX	��q6KGM�YA��0I
    ?��>�'���%
    		7��A��/|�?V�\��w6��?
    J
    		a�7ގß	ß�q6K��.pA��/f?�sʒ_���%
    		�3A��.�m?`���3���Sr
    		a��ގß	ßN�q6K�HGßMA	N�q6K�JA��.�f?�� ���Z��R
    r
    		�%ގ��"��q6K���A	�q6KGMF!5!A��"Z�?����ޠ4~�m	
    �&
    		A�6ގ�����q6K(��q6Kv������\ |������h�b�T����SkR����A��!/�?��;B�-k~�* 
    		�����s�A����?��T��C��Rr
    		�$ގ�O"��q6K���A	�q6KGMF!� A���?����)_~�* 
    		�����X�A��
    �a?��9�����m
    �&
    		A�5ގ�����q6K(��q6KS��w(%@���h����H��D�0vH��Ҁ�7�A� �\uA���S?����6�{�Rr
    		�#ގ�O"��q6K���A	�q6KGMF!�1A���/?�(^�ڵ�{�* 
    		�����%�A����u�?�!p����m
    �&
    		A�4ގ�����q6K(��q6K�vP�j��'��{?IUױ`�v>��A��*�!B�y�A�����G?�,^,�x�" 
    		������A����5
    ���	KeysPacketsZ
    5��mA�~R
    �
    �
    c
    ��R+��;
    �
    �
    *
    	|	U��L%��5��"��v��f?��2�{!�m�R5p
    		A�Dގ��	���q6K(�q6K��r�M���+�A���@'�E�&����X4|
    		A�Cގ������N�q6K(�q6K���
    ��q�,�xTA��g?������X3|
    		A��ގ��������N�q6K(N�q6K�9D,��[7�_�
    ��+A��N�?��Lv����X2|
    		A�Bގ������N�q6K(�q6K�mG��	�`e�A���B?���^�����X1|
    		A��ގ��������N�q6K(N�q6K)��Z��d�&����h1A���?�ڜ�(Z���%0
    		��A���?e~�E�]��g/
    �
    		a��ގ��H���q6KN�q6K(N�q6K���Y��qԞ%7����д-Z͛A���?����I���%.
    		A5�A��g'?j��!���{-
    �@
    		a�Aގ��H��N�q6K�q6K(�q6K��n.x"7�D����l�c?�IU�y0����4.|�	-���A��1�?u"���/���%,
    		@��A���#?e~�E�]��g+
    �
    		a�@ގ��H��N�q6K�q6K(�q6K��ׅR����1�O-�I+�|K؝A���%?����3���%*
    		�{�A����?f�\��w6��k)
    � 
    		a��ގ��H���q6KN�q6K(N�q6K��>��̺�#5%+&���'d2��A��|�?�!��}���%(
    		>EmA��
    4�?jy�ɟ���z'
    �>
    		a�>ގ��H��N�q6K�q6K1a0�q6KO<��|�0�{�S#?����I�	ޣ^Y;�ڙA��	��?�:�}��%&
    		�eA����?b���IӉ��\%
    �
    		a��ގ��H���q6KN�q6K�N�q6K2_�pm\��A����?}�̒j��%$
    		=�_A��/?g��9����o#
    �(
    		a�=ގ��H��N�q6K�q6K`%N�q6Kq_ �q6K���X�ԶiE���ȵA����?�/��g��%"
    		<WNA��fk?`@��>!��R!p
    		a�<ގ��H��N�q6K�q6K^	N�q6K��mA��E�?��I�����% 
    		��WA���]W?g�|�&���m
    �$
    		a��ގ��H��	�q6KN�q6K�#N�q6KQ�N�q6K�d�`�rhpcpVk�KSx�A���/4?��<�P;���%
    		�FA��Сb?a�g�Lf��X|
    		a��ގ��H���q6KN�q6K�N�q6K@�\��A���}�?�_���~��%
    		;�:A�����?m\1Y>_��ہ
    �T
    		a�;ގ��H��N�q6K�q6K];N�q6K@@�\'�q6K<��I,��:���n�
    ~MX��pL�a��^f!A�����?_�,+����%
    		:a+A���d?a�g�Lf��X|
    		a�:ގ��H��N�q6K�q6K[N�q6K@�9�A���@y?��.H���%
    		��2A��gB?mz���ہ
    �R
    		a��ގ��H���q6KN�q6K�:N�q6K@@�'N�q6KT��5�B��$��RF,�t���iΫNk׀�p�CR�A��g�?�#�1�S��%
    		9�A��4�?a�g�Lf��X|
    		a�9ގ��H��N�q6K�q6KZN�q6KE��5A��4��?�z�����%
    		�!#A��3�P?e~�E�]��g
    �
    		a��ގ��H���q6KN�q6K�N�q6K@E��	�N�q6K̒A��3�R?��j�@-��%
    		��A��26�?a�g�Lf��X|
    		a��ގ��H���q6KN�q6K�N�q6KEXO�A��2E?��r%�I���%
    		8sA��0w-?g�|�&���m
    �$
    		a�8ގ��H��N�q6K�q6KY#N�q6K@EX	��q6KGM�YA��0I
    ?��>�'���%
    		7��A��/|�?V�\��w6��?
    J
    		a�7ގß	ß�q6K��.pA��/f?�sʒ_���%
    		�3A��.�m?`���3���Sr
    		a��ގß	ßN�q6K�HGßMA	N�q6K�JA��.�f?�� ���Z��R
    r
    		�%ގ��"��q6K���A	�q6KGMF!5!A��"Z�?����ޠ4~�m	
    �&
    		A�6ގ�����q6K(��q6Kv������\ |������h�b�T����SkR����A��!/�?��;B�-k~�* 
    		�����s�A����?��T��C��Rr
    		�$ގ�O"��q6K���A	�q6KGMF!� A���?����)_~�* 
    		�����X�A��
    �a?��9�����m
    �&
    		A�5ގ�����q6K(��q6KS��w(%@���h����H��D�0vH��Ҁ�7�A� �\uA���S?����6�{�Rr
    		�#ގ�O"��q6K���A	�q6KGMF!�1A���/?�(^�ڵ�{�* 
    		�����%�A����u�?�!p����m
    �&
    		A�4ގ�����q6K(��q6K�vP�j��'��{?IUױ`�v>��A��*�!B�y�A�����G?�,^,�x�" 
    		������A����<��
    %��X�^
    �
    d
    �h�m
    �
    s
     	�	y	&�~+��0��6��<��C�QZp
    		A��ގ����	����N�q6K(N�q6K0V,Ҭ6�x�q�A��'{�?�R� #\�QYp
    		A��ގ����	����N�q6K(N�q6K�@���T�{�A��')@D4�6��\�QXp
    		A�Wގ��	���q6K(�q6KEMF[���{��A��&�l?��"��
    kv�QWp
    		A�Vގ��	���q6K(�q6Kp�=i�҈+D3�A��&b-I@(k4a0��v�QVp
    		A��ގ����	����N�q6K(N�q6K���o��k�A��#Tƽ?��5\��\�QUp
    		A��ގ����	����N�q6K(N�q6K�hNH4�$d��A��#:��@r� ě�^�RTp
    		A�Uގ��	���q6K(�q6KkJ�Nt�t�/PA��"�b?پ	�j����RSp
    		A�Tގ��	���q6K(�q6Kҭ�d��I�=�A��"���@(P%�����QRp
    		A��ގ����	����N�q6K(N�q6K8PΛ���zh�<A����8?ڠ��d<�{�QQp
    		A��ގ����	����N�q6K(N�q6K�c|�
    ��-N��A��p��@�]��;~�RPp
    		A�Sގ��	���q6K(�q6K)�S��3y�i�A���<�?��y�|���ROp
    		A�Rގ��	���q6K(�q6K�/%�4�̼�A���YG@(���z��QNp
    		A��ގ����	����N�q6K(N�q6K�BW{&z�AA����V?�W��5��{�QMp
    		A��ގ����	����N�q6K(N�q6KY��M�M}LR;�A���b�@^��@\{�RLp
    		A�Qގ��	���q6K(�q6K��F�ː?c��~A��j�?�܋��_���RKp
    		A�Pގ��	���q6K(�q6K�S$y��}���A����T@(%_5���QJp
    		A��ގ����	����N�q6K(N�q6Ky��Bp%���$A���?��,�
    s�QIp
    		A��ގ����	����N�q6K(N�q6K�}���Q��A��ַ|@B��~s�RHp
    		A�Oގ��	���q6K(�q6K7�)
    �)�%��AA��D�3?��ݨ�#��QGp
    		A�Nގ��	���q6K(�q6K%f�9�J��=�~A��(��@'�F�$[)~�RFp
    		A��ގ����	����N�q6K(N�q6K��*X�O!�4A��,��?�B��~��QEp
    		A��ގ����	����N�q6K(
    N�q6K9�ϝ�7�}��A��u@J<d4\�~�QDp
    		A�Mގ��	���q6K(�q6KF�Ϙ��h��A��w#:?�C�k&��{�QCp
    		A�Lގ��	���q6K(
    �q6K�w�Q���2sa�A��Z�e@'�a�V!{�RBp
    		A��ގ����	����N�q6K(N�q6K�"���-�)�1fA��b�5?�:%������RAp
    		A��ގ����	����N�q6K(N�q6K��b���yV1�CA��G�@v�A��R@p
    		A�Kގ��	���q6K(�q6K�߻U��\A����^?܁
    V�H��R?p
    		A�Jގ��	���q6K(�q6K��V����'
    A���TT@'���q����R>p
    		A��ގ����	����N�q6K(
    N�q6K2�E�	ӻY ֜A����?��u_�mY��R=p
    		A��ގ����	����N�q6K(	N�q6K��н�*S���A���7&@.�}z��Q<p
    		A��ގ����	����N�q6K(N�q6K'�
    ��i�Xl�A����
    ?ۡ� _�s�Q;p
    		A��ގ����	����N�q6K(N�q6K��D�Zz�W�A���Sz@��:�cv�Q:p
    		A�Gގ��	���q6K(�q6K��WK#'�Ke�;A���j?��1[��~�Q9p
    		A�Fގ��	���q6K(�q6K��~��׼�A���9@'x�e�n�~�R8p
    		A��ގ����	����N�q6K(N�q6K�H�����#�A����L?�IёW���R7p
    		A��ގ����	����N�q6K(N�q6K͠�n+��!A���J@N�=�
    R��R6p
    		A�Eގ��	���q6K(�q6K|�Eׇ֍�A��6<�?�D��0<��
    ��,!4NetworkKey
    

    This is a log file. You need to modify the suffix to view it. It seems that the links were not properly set up in the log.

  • hi 

    This is the complete code. I'm sorry, I'm not very familiar with Zboos yet. What else information do you need? Or perhaps the expression was not clear. Please reply here.

    /* door lock.c */
    /******************************************************************************
     Group: CMCU LPRF
     Target Device: cc23xx
    
     ******************************************************************************
     
     Copyright (c) 2024-2025, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
     
     
     *****************************************************************************/
    
    /***** Trace related defines *****/
    #define ZB_TRACE_FILE_ID 40123
    
    /****** Application defines ******/
    #define ZB_OUTPUT_ENDPOINT          5
    #define ZB_OUTPUT_MAX_CMD_PAYLOAD_SIZE 2
    
    #define ZB_SWITCH_ENDPOINT          10
    
    // 0x00 = LOCK, 0x01 = UNLOCK
    #define ZB_ZCL_CMD_DOOR_LOCK_LOCK_ID 0x00
    
    #include <ti/log/Log.h>
    
    #include "ti_zigbee_config.h"
    #include "zboss_api.h"
    #include "zb_led_button.h"
    #include "zboss_api_error.h"
    #include "uart2callback.h"
    #include "zcl/zb_zcl_door_lock.h"
    
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(inc/hw_fcfg.h)
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    
    /* for button handling */
    #include <ti/drivers/GPIO.h>
    #include "ti_drivers_config.h"
    
    #ifdef ZB_CONFIGURABLE_MEM
    #include "zb_mem_config_lprf3.h"
    #endif
    
    /****** Application variables declarations ******/
    zb_uint16_t g_dst_addr;
    zb_uint8_t g_addr_mode;
    zb_uint8_t g_endpoint;
    zb_bool_t perform_factory_reset = ZB_FALSE;
    
    zb_bool_t cmd_in_progress = ZB_FALSE;
    
    /****** Application function declarations ******/
    /* Handler for specific ZCL commands */
    zb_uint8_t zcl_specific_cluster_cmd_handler(zb_uint8_t param);
    void test_device_interface_cb(zb_uint8_t param);
    void send_toggle_req(zb_uint8_t param);
    void button_press_handler(zb_uint8_t param);
    void send_lock_req(zb_uint8_t param, zb_uint8_t lock_or_unlock);
    
    /****** Cluster declarations ******/
    // 隐藏开关的组的属性
    /* On/Off cluster attributes */
    // zb_uint8_t g_attr_on_off = ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE;
    // #ifdef ZB_ENABLE_ZLL
    // /* On/Off cluster attributes additions */
    // zb_bool_t g_attr_global_scene_ctrl  = ZB_TRUE;
    // zb_uint16_t g_attr_on_time  = 0;
    // zb_uint16_t g_attr_off_wait_time  = 0;
    
    // ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST_EXT(on_off_attr_list, &g_attr_on_off,
    //     &g_attr_global_scene_ctrl, &g_attr_on_time, &g_attr_off_wait_time);
    // #else
    // ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(on_off_attr_list, &g_attr_on_off);
    // #endif
    
    // THIS CODE REPLACES IT
      /* Door Lock cluster attributes data */
    zb_uint8_t g_attr_door_lock_lock_state = 0;
    zb_uint8_t g_attr_door_lock_lock_type = 0;
    zb_bool_t g_attr_door_lock_actuator_enabled = ZB_FALSE;
    ZB_ZCL_DECLARE_DOOR_LOCK_ATTRIB_LIST(door_lock_attr_list, &g_attr_door_lock_lock_state,
                                          &g_attr_door_lock_lock_type, &g_attr_door_lock_actuator_enabled);
    
    /* Basic cluster attributes */
    zb_uint8_t g_attr_zcl_version  = ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE;
    zb_uint8_t g_attr_power_source = ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE;
    
    ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(basic_attr_list, &g_attr_zcl_version, &g_attr_power_source);
    
    /* Identify cluster attributes */
    zb_uint16_t g_attr_identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
    
    ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list, &g_attr_identify_time);
    
    /* Groups cluster attributes */
    zb_uint8_t g_attr_name_support = 0;
    
    ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(groups_attr_list, &g_attr_name_support);
    
    #ifdef ZB_ZCL_SUPPORT_CLUSTER_SCENES
    /* Scenes cluster attributes */
    zb_uint8_t g_attr_scenes_scene_count = ZB_ZCL_SCENES_SCENE_COUNT_DEFAULT_VALUE;
    zb_uint8_t g_attr_scenes_current_scene = ZB_ZCL_SCENES_CURRENT_SCENE_DEFAULT_VALUE;
    zb_uint16_t g_attr_scenes_current_group = ZB_ZCL_SCENES_CURRENT_GROUP_DEFAULT_VALUE;
    zb_uint8_t g_attr_scenes_scene_valid = ZB_ZCL_SCENES_SCENE_VALID_DEFAULT_VALUE;
    zb_uint16_t g_attr_scenes_name_support = ZB_ZCL_SCENES_NAME_SUPPORT_DEFAULT_VALUE;
    
    ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(scenes_attr_list, &g_attr_scenes_scene_count,
        &g_attr_scenes_current_scene, &g_attr_scenes_current_group,
        &g_attr_scenes_scene_valid, &g_attr_scenes_name_support);
    #else
    zb_zcl_attr_t scenes_attr_list[] = { ZB_ZCL_NULL_ID, 0, 0, NULL };
    #endif
    
    /* Declare cluster list for the device */
    // ZB_HA_DECLARE_ON_OFF_OUTPUT_CLUSTER_LIST(on_off_output_clusters,
    //                                          on_off_attr_list,
    //                                          basic_attr_list,
    //                                          identify_attr_list,
    //                                          groups_attr_list,
    //                                          scenes_attr_list);
    
    // /* Declare endpoint */
    // ZB_HA_DECLARE_ON_OFF_OUTPUT_EP(on_off_output_ep, ZB_OUTPUT_ENDPOINT, on_off_output_clusters);
    
    // /* Declare application's device context for single-endpoint device */
    // ZB_HA_DECLARE_ON_OFF_OUTPUT_CTX(on_off_output_ctx, on_off_output_ep);
    
    ZB_HA_DECLARE_DOOR_LOCK_CLUSTER_LIST(door_lock_clusters, 
                                    door_lock_attr_list, 
                                    basic_attr_list, identify_attr_list, 
                                    groups_attr_list, scenes_attr_list);
    ZB_HA_DECLARE_DOOR_LOCK_EP(door_lock_ep, ZB_OUTPUT_ENDPOINT, door_lock_clusters);
    ZB_HA_DECLARE_DOOR_LOCK_CTX(device_ctx, door_lock_ep);
    
    
    static zb_bool_t error_ind_handler(zb_uint8_t severity,
                                       zb_ret_t error_code,
                                       void *additional_info);
    
    void off_network_attention(zb_uint8_t param)
    {
      ZVUNUSED(param);
      // uart2_printf("off_network_attention\r\n");
      zb_osif_led_toggle(1);
    
      ZB_SCHEDULE_APP_ALARM(off_network_attention, 0, 1 * ZB_TIME_ONE_SECOND);
    }
    
    //extern void *logThread(void *arg0);
    
    MAIN()
    {
      ARGV_UNUSED;
    
      /* Global ZBOSS initialization */
      ZB_INIT("door_lock");
    
      logThread(NULL); // 日志初始化
      uart2_printf("zboss_start\r\n");
    
      #ifdef ZB_LONG_ADDR
      // use the address that the customer set in the pre-defined symbols tab
      zb_ieee_addr_t g_long_addr = ZB_LONG_ADDR;
      zb_set_long_address(g_long_addr);
      #else
      /* Set the device's long address to the IEEE address pulling from the FCFG of the device */
      zb_ieee_addr_t ieee_mac_addr;
      ZB_MEMCPY(ieee_mac_addr, fcfg->deviceInfo.macAddr, 8);
      zb_set_long_address(ieee_mac_addr);
      #endif // ZB_LONG_ADDR
    
    #ifdef ZB_COORDINATOR_ROLE
      /* Set up defaults for the commissioning */
      zb_set_network_coordinator_role(DEFAULT_CHANLIST);
    
      /* Set keepalive mode to mac data poll so sleepy zeds consume less power */
      zb_set_keepalive_mode(MAC_DATA_POLL_KEEPALIVE); 
    #ifdef DEFAULT_NWK_KEY
      zb_uint8_t nwk_key[16] = DEFAULT_NWK_KEY;
      zb_secur_setup_nwk_key(nwk_key, 0);
    #endif //DEFAULT_NWK_KEY
      zb_nwk_set_max_ed_capacity(MAX_ED_CAPACITY);
    
    #elif defined ZB_ROUTER_ROLE && !defined ZB_COORDINATOR_ROLE
      zb_set_network_router_role(DEFAULT_CHANLIST);
      zb_nwk_set_max_ed_capacity(MAX_ED_CAPACITY);
    
      /* Set keepalive mode to mac data poll so sleepy zeds consume less power */
      zb_set_keepalive_mode(MAC_DATA_POLL_KEEPALIVE); 
    
    #elif defined ZB_ED_ROLE
      zb_set_network_ed_role(DEFAULT_CHANLIST);
    
      /* Set end-device configuration parameters */
      zb_set_ed_timeout(ED_TIMEOUT_VALUE);
      zb_set_rx_on_when_idle(ED_RX_ALWAYS_ON);
    #if ( ED_RX_ALWAYS_ON == ZB_FALSE )
      zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(ED_POLL_RATE));
    #ifdef DISABLE_TURBO_POLL
      // Disable turbo poll feature
      zb_zdo_pim_permit_turbo_poll(ZB_FALSE);
      zb_zdo_pim_set_long_poll_interval(ED_POLL_RATE);
    #endif // DISABLE_TURBO_POLL
    #endif //ED_RX_ALWAYS_ON
    #endif //ZB_ED_ROLE
    
      zb_set_nvram_erase_at_start(ZB_TRUE);
    
    #ifdef ZB_ENABLE_PTA
      zb_enable_pta(0);
    #endif
    
     /* Register device ZCL context */
      ZB_AF_REGISTER_DEVICE_CTX(&device_ctx);
    
      /* Register cluster commands handler for a specific endpoint */
      ZB_AF_SET_ENDPOINT_HANDLER(ZB_OUTPUT_ENDPOINT, zcl_specific_cluster_cmd_handler);
    
      /* Set Device user application callback */
      ZB_ZCL_REGISTER_DEVICE_CB(test_device_interface_cb);
    
      zb_error_register_app_handler(error_ind_handler);
    
      /* Initiate the stack start without starting the commissioning */
      if (zboss_start_no_autostart() != RET_OK)
      {
        uart2_printf("zboss_start failed\r\n");
      }
      else
      {
        GPIO_setConfig(CONFIG_GPIO_BTN1, GPIO_CFG_IN_PU);
        GPIO_setConfig(CONFIG_GPIO_BTN2, GPIO_CFG_IN_PU);
        // if either button 1 or button 2 gets pressed
        zb_bool_t sideButtonPressed = ((GPIO_read((zb_uint8_t)CONFIG_GPIO_BTN1) == 0U) || (GPIO_read((zb_uint8_t)CONFIG_GPIO_BTN2) == 0U));
        // then perform a factory reset
        if (sideButtonPressed)
        {
          perform_factory_reset = ZB_TRUE;
          uart2_printf("performing factory reset\r\n");
        }
    
        zb_osif_led_button_init();
        ZB_SCHEDULE_APP_ALARM(off_network_attention, 0, 1 * ZB_TIME_ONE_SECOND);
    
        /* Call the main loop */
        zboss_main_loop();
      }
    
      MAIN_RETURN(0);
    }
    
    
    static zb_bool_t error_ind_handler(zb_uint8_t severity,
                                        zb_ret_t error_code,
                                        void *additional_info)
    {
      zb_bool_t ret = ZB_FALSE;
      ZVUNUSED(additional_info);
      /* Unused without trace. */
      ZVUNUSED(severity);
    
      user_print("error_ind_handler severity %d error_code %d\r\n", severity, error_code);
    
      if (error_code == ERROR_CODE(ERROR_CATEGORY_MACSPLIT, ZB_ERROR_MACSPLIT_RADIO_HANG))
      {
        uart2_printf("Fatal macsplit error\r\n");
    
        ret = ZB_TRUE;
        /* return TRUE to prevent default error handling by the stack */
      }
      if (error_code == ERROR_CODE(ERROR_CATEGORY_MACSPLIT, ZB_ERROR_MACSPLIT_RADIO_REBOOT))
      {
        uart2_printf("macsplit radio reboot\r\n");
    
        ret = ZB_TRUE;
      }
      user_print("error_ind_handler ret %d\r\n", ret);
      return ret;
    }
    
    
    void test_device_interface_cb(zb_uint8_t param)
    {
      zb_zcl_device_callback_param_t *device_cb_param =
        ZB_BUF_GET_PARAM(param, zb_zcl_device_callback_param_t);
    
      user_print("> test_device_interface_cb param %d id 0x%x\r\n",
                 param, device_cb_param->device_cb_id);
    
      device_cb_param->status = RET_OK;
    
      switch (device_cb_param->device_cb_id)
      {
        case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
          if (device_cb_param->cb_param.set_attr_value_param.cluster_id == ZB_ZCL_CLUSTER_ID_ON_OFF &&
              device_cb_param->cb_param.set_attr_value_param.attr_id == ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID)
          {
            if (device_cb_param->cb_param.set_attr_value_param.values.data8)
            {
              uart2_printf("set ON\r\n");
    #ifdef ZB_USE_BUTTONS
              //zb_osif_led_on(0);
    #endif
            }
            else
            {
              uart2_printf("set OFF\r\n");
    #ifdef ZB_USE_BUTTONS
              //zb_osif_led_off(0);
    #endif
            }
          }
          else if (device_cb_param->cb_param.set_attr_value_param.cluster_id == ZB_ZCL_CLUSTER_ID_IDENTIFY &&
                   device_cb_param->cb_param.set_attr_value_param.attr_id == ZB_ZCL_ATTR_IDENTIFY_IDENTIFY_TIME_ID)
          {
            user_print("identify time changed to %d (0x%x)\r\n",
                       device_cb_param->cb_param.set_attr_value_param.values.data16, device_cb_param->cb_param.set_attr_value_param.values.data16);
          }
          else
          {
            /* MISRA rule 15.7 requires empty 'else' branch. */
          }
          break;
        case ZB_ZCL_DOOR_LOCK_LOCK_DOOR_CB_ID:
        {
          zb_uint8_t lock_state = ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED;
          uart2_printf("Lock the door");
          ZVUNUSED(zb_zcl_set_attr_val(ZB_OUTPUT_ENDPOINT,
                                      ZB_ZCL_CLUSTER_ID_DOOR_LOCK,
                                      ZB_ZCL_CLUSTER_SERVER_ROLE,
                                      ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID,
                                      &lock_state,
                                      ZB_FALSE));
          zb_osif_led_on(0);
        }
        break;
        case ZB_ZCL_DOOR_LOCK_UNLOCK_DOOR_CB_ID:
        {
          zb_uint8_t lock_state = ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED;
          uart2_printf("Unlock the door");
          ZVUNUSED(zb_zcl_set_attr_val(ZB_OUTPUT_ENDPOINT,
                                      ZB_ZCL_CLUSTER_ID_DOOR_LOCK,
                                      ZB_ZCL_CLUSTER_SERVER_ROLE,
                                      ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID,
                                      &lock_state,
                                      ZB_FALSE));
          zb_osif_led_off(0);
        }
        break;
    
        default:
          device_cb_param->status = RET_ERROR;
          break;
      }
    
      user_print("< test_device_interface_cb %d\r\n", device_cb_param->status);
    }
    
    
    
    static void handle_diag_data_resp(zb_bufid_t buf)
    {
      zb_zdo_get_diag_data_resp_params_t *resp_params;
    
      resp_params = ZB_BUF_GET_PARAM(buf, zb_zdo_get_diag_data_resp_params_t);
    
      ZVUNUSED(resp_params);
    
      user_print("handle_diag_data_resp, status: %d, addr: 0x%x, lqi: %d, rssi: %d\r\n",
                 resp_params->status, resp_params->short_address,
                 resp_params->lqi, resp_params->rssi);
    
      zb_buf_free(buf);
    }
    
    static void send_diag_data_req(zb_uint16_t short_address)
    {
      zb_zdo_get_diag_data_req_params_t *req;
      zb_bufid_t buf;
    
      buf = zb_buf_get_out();
      if (buf != ZB_BUF_INVALID)
      {
        req = ZB_BUF_GET_PARAM(buf, zb_zdo_get_diag_data_req_params_t);
        ZB_BZERO(req, sizeof(*req));
    
        req->short_address = short_address;
        zb_zdo_get_diag_data_async(buf, handle_diag_data_resp);
      }
      else
      {
        uart2_printf("Failed to get a buffer\r\n");
      }
    }
    
    zb_uint8_t zcl_specific_cluster_cmd_handler(zb_uint8_t param)
    {
      zb_zcl_parsed_hdr_t cmd_info;
    
      uart2_printf("> zcl_specific_cluster_cmd_handler\r\n");
    
      ZB_ZCL_COPY_PARSED_HEADER(param, &cmd_info);
    
      g_dst_addr = ZB_ZCL_PARSED_HDR_SHORT_DATA(&cmd_info).source.u.short_addr;
      g_endpoint = ZB_ZCL_PARSED_HDR_SHORT_DATA(&cmd_info).src_endpoint;
      g_addr_mode = ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
    
      ZB_ZCL_DEBUG_DUMP_HEADER(&cmd_info);
      user_print("payload size: %i\r\n", zb_buf_len(param));
    
      send_diag_data_req(g_dst_addr);
    
      if (cmd_info.cmd_direction == ZB_ZCL_FRAME_DIRECTION_TO_CLI)
      {
        uart2_printf("Unsupported \"from server\" command direction\r\n");
        cmd_in_progress = ZB_FALSE;
      }
    
      uart2_printf("< zcl_specific_cluster_cmd_handler\r\n");
      return ZB_FALSE;
    }
    
    void send_toggle_req(zb_uint8_t param)
    {
      zb_uint16_t addr = 0;
    
      ZB_ASSERT(param);
    
      if (ZB_JOINED()  && !cmd_in_progress)
      {
        cmd_in_progress = ZB_TRUE;
        user_print("send_toggle_req %d - send toggle\r\n", param);
    
        /* Destination address and endpoint are unknown; command will be sent via binding */
        ZB_ZCL_ON_OFF_SEND_TOGGLE_REQ(
          param,
          addr,
          ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT,
          0,
          ZB_SWITCH_ENDPOINT,
          ZB_AF_HA_PROFILE_ID,
          ZB_FALSE, NULL);
      }
      else
      {
        user_print("send_toggle_req %d - not joined\r\n", param);
        zb_buf_free(param);
      }
    }
    
    void send_lock_req(zb_uint8_t param, zb_uint8_t lock_or_unlock)
    {
      zb_uint16_t addr = 0;
    
      ZB_ASSERT(param);
    
      if (ZB_JOINED() ) // && !cmd_in_progress
      {
        cmd_in_progress = ZB_TRUE;
    
        user_print("send_lock_req %d - sending %s command\r\n", param,
                    "LOCK" );
    
        /* Send Door Lock command via binding (destination unknown) */ // ZB_ZCL_DOOR_LOCK_SEND_LOCK_DOOR_REQ
        ZB_ZCL_DOOR_LOCK_SEND_LOCK_DOOR_REQ(
          param,
          addr,
          ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT,
          0,                       // no addr/endpoint needed because using binding
          ZB_SWITCH_ENDPOINT,      // source endpoint
          ZB_FALSE,                // no default response
          NULL);         // command: 0x00 = LOCK, 0x01 = UNLOCK
      }
      else
      {
        user_print("send_lock_req %d - not joined or busy\r\n", param);
        zb_buf_free(param);
      }
    }
    
    void restart_commissioning(zb_uint8_t param)
    {
      ZVUNUSED(param);
      bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
    }
    
    void button_press_handler(zb_uint8_t param)
    {
      ZVUNUSED(param);
      uart2_printf("button is pressed, do nothing\r\n");
      if (!param)
      {
        /* Button is pressed, gets buffer for outgoing command */
        zb_buf_get_out_delayed(button_press_handler);
      }
      else
      {
        user_print("button_press_handler %d\r\n", param);
        // send_toggle_req(param);
        send_lock_req(param, ZB_ZCL_CMD_DOOR_LOCK_LOCK_ID);
    #ifndef ZB_USE_BUTTONS
        /* Do not have buttons in simulator - just start periodic on/off sending */
        ZB_SCHEDULE_APP_ALARM(button_press_handler, 0, 7 * ZB_TIME_ONE_SECOND);
    #endif
      }
    }
    
    /* Callback to handle the stack events */
    void zboss_signal_handler(zb_uint8_t param)
    {
      zb_zdo_app_signal_type_t sig = zb_get_app_signal(param, NULL);
    
      if (ZB_GET_APP_SIGNAL_STATUS(param) == 0)
      {
        switch(sig)
        {
    #ifndef ZB_MACSPLIT_HOST
          case ZB_ZDO_SIGNAL_SKIP_STARTUP:
    #else
          case ZB_MACSPLIT_DEVICE_BOOT:
    #endif /* ZB_MACSPLIT_HOST */
    
    #ifdef TEST_USE_INSTALLCODE
            zb_secur_ic_str_add(g_ed_addr, g_installcode, NULL);
    #endif
            zboss_start_continue();
            break;
    
          case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
          case ZB_BDB_SIGNAL_DEVICE_REBOOT:
          {
            zb_nwk_device_type_t device_type = ZB_NWK_DEVICE_TYPE_NONE;
            device_type = zb_get_device_type();
            ZVUNUSED(device_type);
            user_print("Device (%d) STARTED OK\r\n", device_type);
            if (perform_factory_reset)
            {
              uart2_printf("Performing a factory reset.\r\n");
              zb_bdb_reset_via_local_action(0);
              perform_factory_reset = ZB_FALSE;
            }
            bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
    
    #ifdef ZB_USE_BUTTONS
            zb_button_register_handler(0, 0, button_press_handler);
    #endif
            break;
          }
          case ZB_COMMON_SIGNAL_CAN_SLEEP:
          {
    #ifdef ZB_USE_SLEEP
            // uart2_printf("Sleeping now");
            zb_sleep_now();
    #endif
            break;
          }
          case ZB_BDB_SIGNAL_STEERING:
            uart2_printf("Successful steering, start f&b target\r\n");
            zb_bdb_finding_binding_target(ZB_OUTPUT_ENDPOINT);
            ZB_SCHEDULE_APP_ALARM_CANCEL(off_network_attention, ZB_ALARM_ANY_PARAM);
            zb_osif_led_off(1);
            break;
    
          default:
            user_print("Unknown signal %d\r\n", (zb_uint16_t)sig);
        }
      }
      else
      {
        switch(sig)
        { 
          case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
            uart2_printf("Device can not find any network on start, so try to perform network steering\r\n");
            ZB_SCHEDULE_APP_ALARM(restart_commissioning, 0, 10 * ZB_TIME_ONE_SECOND);
            break; /* ZB_BDB_SIGNAL_DEVICE_FIRST_START */
    
          case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY:
            uart2_printf("Production config is not present or invalid\r\n");
            break;
    
          case ZB_BDB_SIGNAL_STEERING:
            uart2_printf("Steering failed, retrying again in 10 seconds\r\n");
            ZB_SCHEDULE_APP_ALARM(restart_commissioning, 0, 10 * ZB_TIME_ONE_SECOND);
            break; /* ZB_BDB_SIGNAL_STEERING */
    
          default:
            user_print("Device started FAILED status %d sig %d\r\n", ZB_GET_APP_SIGNAL_STATUS(param), sig);
        }
      }
    
      /* Free the buffer if it is not used */
      if (param)
      {
        zb_buf_free(param);
      }
    }
    

    Best Regards, 
    yongjian

  • Hi Yongjian,

    First, you can enable logging in the SysConfig file, along with any additional options from the "Log Configuration" drop-down windows.

    Then follow this Logging SimpleLink Academy Lab (instructions are for the F2 SDK but should mostly apply for F3 as well) along with the TI Log Tool User's Guide.  This is uni-directional (i.e. CC2340R5 TX only).

    If bi-directional is necessary (i.e. CC2340R5 RX/TX) then your current implementation is at fault for calling a logThread function which never leaves (i.e. while 1 forever) and thus does not allow the Zigbee application to operate.  

    I will speak with R&D about what can be done to resolve this.

    Regards,
    Ryan

  • Using Using www.ti.com/.../4.0.3.LTS here is a reference for the on_off_switch that enabled a UART2 callback echo using a CONFIG_UART2_ZB module added to SysConfig using the backchannel XDS110 UART channel.

    /******************************************************************************
     Group: CMCU LPRF
     Target Device: cc23xx
    
     ******************************************************************************
     
     Copyright (c) 2024-2025, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
     
     
     *****************************************************************************/
    
    /***** Trace related defines *****/
    #define ZB_TRACE_FILE_ID 40124
    
    /****** Application defines ******/
    #define ZB_SWITCH_ENDPOINT          10
    
    #include <ti/log/Log.h>
    
    #include "ti_zigbee_config.h"
    #include "zboss_api.h"
    #include "zb_led_button.h"
    
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(inc/hw_fcfg.h)
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    
    /* for button handling */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART2.h>
    #include "ti_drivers_config.h"
    
    #ifdef ZB_CONFIGURABLE_MEM
    #include "zb_mem_config_lprf3.h"
    #endif
    
    #if !defined ZB_ED_FUNC
    #error define ZB_ED_ROLE to compile the tests
    #endif
    
    char input;
    const char echoPrompt[] = "Echoing characters:\r\n";
    UART2_Handle uart;
    UART2_Params uartParams;
    uint32_t status = UART2_STATUS_SUCCESS;
    static volatile size_t numBytesRead;
    
    /****** Application variables declarations ******/
    /* IEEE address of the device */
    zb_bool_t cmd_in_progress = ZB_FALSE;
    zb_bool_t perform_factory_reset = ZB_FALSE;
    
    /****** Application function declarations ******/
    zb_uint8_t zcl_specific_cluster_cmd_handler(zb_uint8_t param);
    void on_off_read_attr_resp_handler(zb_bufid_t cmd_buf);
    void send_toggle_req(zb_uint8_t param);
    void button_press_handler(zb_uint8_t param);
    //void uart_handler(zb_uint8_t param);
    
    /****** Cluster declarations ******/
    /* Switch config cluster attributes */
    zb_uint8_t attr_switch_type =
        ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_TYPE_TOGGLE;
    zb_uint8_t attr_switch_actions =
        ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_DEFAULT_VALUE;
    
    ZB_ZCL_DECLARE_ON_OFF_SWITCH_CONFIGURATION_ATTRIB_LIST(switch_cfg_attr_list,
                                                           &attr_switch_type,
                                                           &attr_switch_actions);
    /* Basic cluster attributes */
    zb_uint8_t attr_zcl_version  = ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE;
    zb_uint8_t attr_power_source = ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE;
    ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(basic_attr_list, &attr_zcl_version, &attr_power_source);
    /* Identify cluster attributes */
    zb_uint16_t attr_identify_time = 0;
    ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list, &attr_identify_time);
    /* Declare cluster list for the device */
    ZB_HA_DECLARE_ON_OFF_SWITCH_CLUSTER_LIST(on_off_switch_clusters,
                                             switch_cfg_attr_list,
                                             basic_attr_list,
                                             identify_attr_list);
    /* Declare endpoint */
    ZB_HA_DECLARE_ON_OFF_SWITCH_EP(on_off_switch_ep, ZB_SWITCH_ENDPOINT, on_off_switch_clusters);
    /* Declare application's device context for single-endpoint device */
    ZB_HA_DECLARE_ON_OFF_SWITCH_CTX(on_off_switch_ctx, on_off_switch_ep);
    
    void uart_callback(zb_bufid_t param, zb_uint16_t count)
    {
      numBytesRead = count;
    
      if (numBytesRead > 0)
      {
          status = UART2_write(uart, &input, 1, NULL);
    
          if (status != UART2_STATUS_SUCCESS)
          {
              /* UART2_write() failed */
              while (1) {}
          }
      }
    
      numBytesRead = 0;
    
      /* Pass NULL for bytesRead since it's not used in this example */
      status = UART2_read(uart, &input, 1, NULL);
    
      if (status != UART2_STATUS_SUCCESS)
      {
          /* UART2_read() failed */
          while (1) {}
      }
    }
    
    void schedule_uart_callback (zb_uint8_t count) {
        zb_buf_get_out_delayed_ext(uart_callback, count, 0);
    }
    
    /*
     *  ======== callbackFxn ========
     */
    void callbackFxn(UART2_Handle handle, void *buffer, size_t count, void *userArg, int_fast16_t status)
    {
      ZB_SCHEDULE_APP_CALLBACK(schedule_uart_callback, count);
    }
    
    void my_main_loop()
    {
      while (1)
      {
        /* ... User code ... */
        zboss_main_loop_iteration();
        /* ... User code ... */
      }
    }
    
    void off_network_attention(zb_uint8_t param)
    {
      ZVUNUSED(param);
      Log_printf(LogModule_Zigbee_App, Log_INFO, "off_network_attention");
      zb_osif_led_toggle(1);
    
      ZB_SCHEDULE_APP_ALARM(off_network_attention, 0, 1 * ZB_TIME_ONE_SECOND);
    }
    
    MAIN()
    {
      ARGV_UNUSED;
    
      /* Global ZBOSS initialization */
      ZB_INIT("on_off_switch");
    
      #ifdef ZB_LONG_ADDR
      // use the address that the customer set in the pre-defined symbols tab
      zb_ieee_addr_t g_long_addr = ZB_LONG_ADDR;
      zb_set_long_address(g_long_addr);
      #else
      /* Set the device's long address to the IEEE address pulling from the FCFG of the device */
      zb_ieee_addr_t ieee_mac_addr;
      ZB_MEMCPY(ieee_mac_addr, fcfg->deviceInfo.macAddr, 8);
      zb_set_long_address(ieee_mac_addr);
      #endif // ZB_LONG_ADDR
    
    #ifdef ZB_COORDINATOR_ROLE
      zb_set_network_coordinator_role(DEFAULT_CHANLIST);
    
      /* Set keepalive mode to mac data poll so sleepy zeds consume less power */
      zb_set_keepalive_mode(MAC_DATA_POLL_KEEPALIVE); 
    #ifdef DEFAULT_NWK_KEY
      zb_uint8_t nwk_key[16] = DEFAULT_NWK_KEY;
      zb_secur_setup_nwk_key(nwk_key, 0);
    #endif //DEFAULT_NWK_KEY
    
    #ifdef ZBOSS_REV23
      zb_nwk_set_max_ed_capacity(MAX_ED_CAPACITY);
    #endif //ZBOSS_REV23
    
    #elif defined ZB_ROUTER_ROLE && !defined ZB_COORDINATOR_ROLE
      zb_set_network_router_role(DEFAULT_CHANLIST);
    
    #ifdef ZBOSS_REV23
      zb_nwk_set_max_ed_capacity(MAX_ED_CAPACITY);
    #endif //ZBOSS_REV23
    
      /* Set keepalive mode to mac data poll so sleepy zeds consume less power */
      zb_set_keepalive_mode(MAC_DATA_POLL_KEEPALIVE); 
    
    #elif defined ZB_ED_ROLE
      zb_set_network_ed_role(DEFAULT_CHANLIST);
    
      /* Set end-device configuration parameters */
      zb_set_ed_timeout(ED_TIMEOUT_VALUE);
      zb_set_rx_on_when_idle(ED_RX_ALWAYS_ON);
    #if ( ED_RX_ALWAYS_ON == ZB_FALSE )
      zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(ED_POLL_RATE));
    #ifdef DISABLE_TURBO_POLL
      // Disable turbo poll feature
      zb_zdo_pim_permit_turbo_poll(ZB_FALSE);
      zb_zdo_pim_set_long_poll_interval(ED_POLL_RATE);
    #endif // DISABLE_TURBO_POLL
    #endif // ED_RX_ALWAYS_ON
    #endif //ZB_ED_ROLE
    
      zb_set_nvram_erase_at_start(ZB_FALSE);
    
      /* Register device ZCL context */
      ZB_AF_REGISTER_DEVICE_CTX(&on_off_switch_ctx);
      /* Register cluster commands handler for a specific endpoint */
      ZB_AF_SET_ENDPOINT_HANDLER(ZB_SWITCH_ENDPOINT, zcl_specific_cluster_cmd_handler);
    
        /* Create a UART in CALLBACK read mode */
      UART2_Params_init(&uartParams);
      uartParams.readMode     = UART2_Mode_CALLBACK;
      uartParams.readCallback = callbackFxn;
      uartParams.baudRate     = 115200;
    
      uart = UART2_open(CONFIG_UART2_ZB, &uartParams);
    
      if (uart == NULL)
      {
          /* UART2_open() failed */
          while (1) {}
      }
    
      /* Pass NULL for bytesWritten since it's not used in this example */
      UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
    
      numBytesRead = 0;
    
      /* Pass NULL for bytesRead since it's not used in this example */
      status = UART2_read(uart, &input, 1, NULL);
    
      if (status != UART2_STATUS_SUCCESS)
      {
          /* UART2_read() failed */
          while (1) {}
      }
    
      /* Initiate the stack start without starting the commissioning */
      if (zboss_start_no_autostart() != RET_OK)
      {
        Log_printf(LogModule_Zigbee_App, Log_ERROR, "zboss_start failed");
      }
      else
      {
        GPIO_setConfig(CONFIG_GPIO_BTN1, GPIO_CFG_IN_PU);
        GPIO_setConfig(CONFIG_GPIO_BTN2, GPIO_CFG_IN_PU);
        // if either button 1 or button 2 gets pressed
        zb_bool_t sideButtonPressed = ((GPIO_read((zb_uint8_t)CONFIG_GPIO_BTN1) == 0U) || (GPIO_read((zb_uint8_t)CONFIG_GPIO_BTN2) == 0U));
        // then perform a factory reset
        if (sideButtonPressed)
        {
          perform_factory_reset = ZB_TRUE;
          Log_printf(LogModule_Zigbee_App, Log_INFO, "perform factory reset");
        }
    
        zb_osif_led_button_init();
    #ifndef ZB_COORDINATOR_ROLE
        ZB_SCHEDULE_APP_ALARM(off_network_attention, 0, 1 * ZB_TIME_ONE_SECOND);
    #endif /* ZB_COORDINATOR_ROLE */
        
        /* Call the application-specific main loop */
        my_main_loop();
      }
    
      MAIN_RETURN(0);
    }
    
    static zb_bool_t finding_binding_cb(zb_int16_t status,
                                        zb_ieee_addr_t addr,
                                        zb_uint8_t ep,
                                        zb_uint16_t cluster)
    {
      /* Unused without trace. */
      ZVUNUSED(status);
      ZVUNUSED(addr);
      ZVUNUSED(ep);
      ZVUNUSED(cluster);
    
      Log_printf(LogModule_Zigbee_App, Log_INFO, "finding_binding_cb status %d addr %x ep %d cluster %d",
                 status, ((zb_uint32_t *)addr)[0], ep, cluster);
      return ZB_TRUE;
    }
    
    zb_uint8_t zcl_specific_cluster_cmd_handler(zb_uint8_t param)
    {
      zb_zcl_parsed_hdr_t *cmd_info = ZB_BUF_GET_PARAM(param, zb_zcl_parsed_hdr_t);
      zb_bool_t unknown_cmd_received = ZB_TRUE;
    
      Log_printf(LogModule_Zigbee_App, Log_INFO, "> zcl_specific_cluster_cmd_handler %i", param);
      Log_printf(LogModule_Zigbee_App, Log_INFO, "payload size: %i", zb_buf_len(param));
    
      if (cmd_info->cmd_direction == ZB_ZCL_FRAME_DIRECTION_TO_CLI)
      {
        if (cmd_info->cmd_id == ZB_ZCL_CMD_DEFAULT_RESP)
        {
          unknown_cmd_received = ZB_FALSE;
    
          cmd_in_progress = ZB_FALSE;
    
          zb_buf_free(param);
        }
      }
    
      Log_printf(LogModule_Zigbee_App, Log_INFO, "< zcl_specific_cluster_cmd_handler %i", param);
      return ! unknown_cmd_received;
    }
    
    void send_toggle_req(zb_uint8_t param)
    {
      zb_uint16_t addr = 0;
    
      ZB_ASSERT(param);
    
      if (ZB_JOINED()  && !cmd_in_progress)
      {
        cmd_in_progress = ZB_TRUE;
        Log_printf(LogModule_Zigbee_App, Log_INFO, "send_toggle_req %d - send toggle", param);
    
        /* Destination address and endpoint are unknown; command will be sent via binding */
        ZB_ZCL_ON_OFF_SEND_TOGGLE_REQ(
          param,
          addr,
          ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT,
          0,
          ZB_SWITCH_ENDPOINT,
          ZB_AF_HA_PROFILE_ID,
          ZB_FALSE, NULL);
      }
      else
      {
        Log_printf(LogModule_Zigbee_App, Log_INFO, "send_toggle_req %d - not joined", param);
        zb_buf_free(param);
      }
    }
    
    void restart_commissioning(zb_uint8_t param)
    {
      ZVUNUSED(param);
      bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
    }
    
    void button_press_handler(zb_uint8_t param)
    {
      if (!param)
      {
        /* Button is pressed, gets buffer for outgoing command */
        zb_buf_get_out_delayed(button_press_handler);
      }
      else
      {
        Log_printf(LogModule_Zigbee_App, Log_INFO, "button_press_handler %d", param);
        send_toggle_req(param);
    #ifndef ZB_USE_BUTTONS
        /* Do not have buttons in simulator - just start periodic on/off sending */
        ZB_SCHEDULE_APP_ALARM(button_press_handler, 0, 7 * ZB_TIME_ONE_SECOND);
    #endif
      }
    }
    
    // void uart_handler(zb_uint8_t param)
    // {
    //   if (!param)
    //   {
    //     zb_buf_get_out_delayed(uart_handler);
    //   }
    //   else
    //   {
    //     Log_printf(LogModule_Zigbee_App, Log_INFO, "uart_handler %d", param);
    //     zb_osif_serial_put_bytes(&param, 1);
    //   }
    // }
    
    void permit_joining_cb(zb_uint8_t param)
    {
      Log_printf(LogModule_Zigbee_App, Log_INFO, "permit joining done");
      zb_buf_free(param);
    }
    
    void start_finding_binding(zb_uint8_t param)
    {
      ZVUNUSED(param);
    
      Log_printf(LogModule_Zigbee_App, Log_INFO, "Successful steering, start f&b initiator");
      zb_bdb_finding_binding_initiator(ZB_SWITCH_ENDPOINT, finding_binding_cb);
    }
    
    void zboss_signal_handler(zb_uint8_t param)
    {
      zb_zdo_app_signal_hdr_t *sg_p = NULL;
      zb_zdo_app_signal_type_t sig = zb_get_app_signal(param, &sg_p);
      zb_bufid_t buf;
      zb_bufid_t req_buf = 0;
      zb_zdo_mgmt_permit_joining_req_param_t *req_param;
    
      if (ZB_GET_APP_SIGNAL_STATUS(param) == 0)
      {
        switch(sig)
        {
          case ZB_ZDO_SIGNAL_SKIP_STARTUP:
    #ifndef ZB_MACSPLIT_HOST
            Log_printf(LogModule_Zigbee_App, Log_INFO, "ZB_ZDO_SIGNAL_SKIP_STARTUP: boot, not started yet");
            zboss_start_continue();
    #endif /* ZB_MACSPLIT_HOST */
            break;
    
    #ifdef ZB_MACSPLIT_HOST
          case ZB_MACSPLIT_DEVICE_BOOT:
            Log_printf(LogModule_Zigbee_App, Log_INFO, "ZB_MACSPLIT_DEVICE_BOOT: boot, not started yet");
            zboss_start_continue();
            break;
    #endif /* ZB_MACSPLIT_HOST */
          case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
            Log_printf(LogModule_Zigbee_App, Log_INFO, "FIRST_START: start steering");
            if (perform_factory_reset)
            {
              // passing in 0 as the parameter means that a buffer will be allocated automatically for the reset
              zb_bdb_reset_via_local_action(0);
              perform_factory_reset = ZB_FALSE;
            }
            bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
    
            buf = zb_buf_get_out();
            if (!buf)
            {
              Log_printf(LogModule_Zigbee_App, Log_WARNING, "no buffer available");
              break;
            }
    
            req_param = ZB_BUF_GET_PARAM(buf, zb_zdo_mgmt_permit_joining_req_param_t);
    
            req_param->dest_addr = 0xfffc;
            req_param->permit_duration = 0;
            req_param->tc_significance = 1;
    
            zb_zdo_mgmt_permit_joining_req(buf, permit_joining_cb);
          
    #ifdef ZB_USE_BUTTONS
            zb_button_register_handler(0, 0, button_press_handler);
    #endif /* ZB_USE_BUTTONS */
            break;
          case ZB_BDB_SIGNAL_DEVICE_REBOOT:
            Log_printf(LogModule_Zigbee_App, Log_INFO, "Device RESTARTED OK");
            if (perform_factory_reset)
            {
              Log_printf(LogModule_Zigbee_App, Log_INFO, "Performing a factory reset.");
              zb_bdb_reset_via_local_action(0);
              perform_factory_reset = ZB_FALSE;
            }
            else
            {
              ZB_SCHEDULE_APP_ALARM_CANCEL(off_network_attention, ZB_ALARM_ANY_PARAM);
              zb_osif_led_off(1);
            }
    #ifdef ZB_USE_BUTTONS
            zb_button_register_handler(0, 0, button_press_handler);
    #endif /* ZB_USE_BUTTONS */
            break;
    #ifdef ZB_COORDINATOR_ROLE
          case ZB_ZDO_SIGNAL_DEVICE_ANNCE:
    #else
          case ZB_BDB_SIGNAL_TC_REJOIN_DONE:
            Log_printf(LogModule_Zigbee_App, Log_INFO, "TC rejoin is completed successfully");
          case ZB_BDB_SIGNAL_STEERING:
    #endif
          {
            zb_nwk_device_type_t device_type = ZB_NWK_DEVICE_TYPE_NONE;
            device_type = zb_get_device_type();
            ZVUNUSED(device_type);
            Log_printf(LogModule_Zigbee_App, Log_INFO, "Device (%d) STARTED OK", device_type);
            ZB_SCHEDULE_APP_ALARM(start_finding_binding, 0, 3 * ZB_TIME_ONE_SECOND);
            ZB_SCHEDULE_APP_ALARM_CANCEL(off_network_attention, ZB_ALARM_ANY_PARAM);
    #ifdef ZB_USE_BUTTONS
            zb_button_register_handler(0, 0, button_press_handler);
    #endif /* ZB_USE_BUTTONS */
            zb_osif_led_off(1);
            break;
          }
    
          case ZB_BDB_SIGNAL_FINDING_AND_BINDING_INITIATOR_FINISHED:
          {
            Log_printf(LogModule_Zigbee_App, Log_INFO, "Finding&binding done");
    // #ifdef ZB_HAVE_SERIAL
    //         zb_osif_set_uart_byte_received_cb(uart_handler);
    // #endif /*ZB_HAVE_SERIAL*/
    #ifndef ZB_USE_BUTTONS
            /* Do not have buttons in simulator - just start periodic on/off sending */
            cmd_in_progress = ZB_FALSE;
            ZB_SCHEDULE_APP_ALARM_CANCEL(button_press_handler, ZB_ALARM_ANY_PARAM);
            ZB_SCHEDULE_APP_ALARM(button_press_handler, 0, 7 * ZB_TIME_ONE_SECOND);
    #endif
          }
          break;
    
          case ZB_ZDO_SIGNAL_LEAVE:
          break;
          case ZB_COMMON_SIGNAL_CAN_SLEEP:
          {
    #ifdef ZB_USE_SLEEP
            zb_sleep_now();
    #endif
            break;
          }
          case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY:
          {
            Log_printf(LogModule_Zigbee_App, Log_INFO, "Production config is ready");
            break;
          }
    
          default:
            Log_printf(LogModule_Zigbee_App, Log_WARNING, "Unknown signal %d, do nothing", sig);
        }
      }
      else
      {
        switch (sig)
        {
          case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
            Log_printf(LogModule_Zigbee_App, Log_WARNING, "Device can not find any network on start, so try to perform network steering");
            ZB_SCHEDULE_APP_ALARM(restart_commissioning, 0, 10 * ZB_TIME_ONE_SECOND);
            break; /* ZB_BDB_SIGNAL_DEVICE_FIRST_START */
    
          case ZB_BDB_SIGNAL_DEVICE_REBOOT:
            Log_printf(LogModule_Zigbee_App, Log_WARNING, "Device can not find any network on restart");
    
            if (zb_bdb_is_factory_new())
            {
              /* Device tried to perform TC rejoin after reboot and lost its authentication flag.
               * Do nothing here and wait for ZB_BDB_SIGNAL_TC_REJOIN_DONE to handle TC rejoin error */
              Log_printf(LogModule_Zigbee_App, Log_WARNING, "Device lost authentication flag");
            }
            else
            {
              /* Device tried to perform secure rejoin, but didn't found any networks or can't decrypt Rejoin Response
               * (it is possible when Trust Center changes network key when ZED is powered off) */
              Log_printf(LogModule_Zigbee_App, Log_WARNING, "Device is still authenticated, try to perform TC rejoin");
              ZB_SCHEDULE_APP_ALARM(zb_bdb_initiate_tc_rejoin, 0, ZB_TIME_ONE_SECOND);
            }
            break; /* ZB_BDB_SIGNAL_DEVICE_REBOOT */
    
          case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY:
            Log_printf(LogModule_Zigbee_App, Log_INFO, "Production config is not present or invalid");
            break; /* ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY */
    
          case ZB_BDB_SIGNAL_TC_REJOIN_DONE:
            Log_printf(LogModule_Zigbee_App, Log_WARNING, "TC rejoin failed, so try it again with interval");
    
            ZB_SCHEDULE_APP_ALARM(zb_bdb_initiate_tc_rejoin, 0, 3 * ZB_TIME_ONE_SECOND);
            break; /* ZB_BDB_SIGNAL_TC_REJOIN_DONE */
    
          case ZB_BDB_SIGNAL_STEERING:
            Log_printf(LogModule_Zigbee_App, Log_WARNING, "Steering failed, retrying again in 10 seconds");
            ZB_SCHEDULE_APP_ALARM(restart_commissioning, 0, 10 * ZB_TIME_ONE_SECOND);
            break; /* ZB_BDB_SIGNAL_STEERING */
    
          default:
            Log_printf(LogModule_Zigbee_App, Log_WARNING, "Unknown signal %hd with error status, do nothing", sig);
            break;
        }
      }
    
      if (param)
      {
        zb_buf_free(param);
      }
    }
    

    Regards,
    Ryan

  • hi 

    Thank you so much. I will try to run it.

    Regards,
    Ryan

  • May I ask for what reason you need bi-directional UART for a Zigbee door lock application?

    Regards,
    Ryan