Exemple #1
0
void testDevice(
    Test * pTest)
{
    bool status = false;
    const char *name = "Patricia";

    status = Device_Set_Object_Instance_Number(0);
    ct_test(pTest, Device_Object_Instance_Number() == 0);
    ct_test(pTest, status == true);
    status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    ct_test(pTest, Device_Object_Instance_Number() == BACNET_MAX_INSTANCE);
    ct_test(pTest, status == true);
    status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE / 2);
    ct_test(pTest,
        Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2));
    ct_test(pTest, status == true);
    status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE + 1);
    ct_test(pTest,
        Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1));
    ct_test(pTest, status == false);


    Device_Set_System_Status(STATUS_NON_OPERATIONAL);
    ct_test(pTest, Device_System_Status() == STATUS_NON_OPERATIONAL);

    ct_test(pTest, Device_Vendor_Identifier() == BACNET_VENDOR_ID);

    Device_Set_Model_Name(name, strlen(name));
    ct_test(pTest, strcmp(Device_Model_Name(), name) == 0);

    return;
}
Exemple #2
0
static void bacnet_init(
    void)
{
#if defined(BACDL_MSTP)
    RS485_Set_Baud_Rate(38400);
    dlmstp_set_mac_address(57);
    dlmstp_set_max_master(127);
    dlmstp_set_max_info_frames(1);
    dlmstp_init(NULL);
#endif
    Device_Set_Object_Instance_Number(11111);
#ifndef DLMSTP_TEST
    /* we need to handle who-is to support dynamic device binding */
    apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
    /* Set the handlers for any confirmed services that we support. */
    /* We must implement read property - it's required! */
    apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
        handler_read_property);
    apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
        handler_reinitialize_device);
    apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
        handler_write_property);
    /* handle communication so we can shutup when asked */
    apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
        handler_device_communication_control);
#endif
}
Exemple #3
0
void BacnetPrepareComm(
    )
{
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    address_init();
    Init_Service_Handlers();
    dlenv_init();
}
Exemple #4
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    BACNET_ADDRESS my_address, broadcast_address;

    (void) argc;
    (void) argv;
    Device_Set_Object_Instance_Number(4194300);
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    datalink_get_broadcast_address(&broadcast_address);
    print_address("Broadcast", &broadcast_address);
    datalink_get_my_address(&my_address);
    print_address("Address", &my_address);
    printf("BACnet stack running...\n");
    /* loop forever */
    for (;;) {
        /* input */

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        if (I_Am_Request) {
            I_Am_Request = false;
            Send_I_Am(&Handler_Transmit_Buffer[0]);
        } else if (Who_Is_Request) {
            Who_Is_Request = false;
            Send_WhoIs(-1, -1);
        } else {
            Read_Properties();
        }

        /* output */

        /* blink LEDs, Turn on or off outputs, etc */

        /* wait for ESC from keyboard before quitting */
        if (kbhit() && (getch() == 0x1B))
            break;
    }

    print_address_cache();

    return 0;
}
Exemple #5
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = { 0 }; /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */

    (void) argc;
    (void) argv;
    Device_Set_Object_Instance_Number(126);
    Init_Service_Handlers();
    RTOS_Initialize();
    /* init the physical layer */
#ifdef BACDL_MSTP
    dlmstp_set_my_address(0x05);
#endif
    datalink_init(NULL);
    Send_I_Am(&Handler_Transmit_Buffer[0]);
    /* loop forever */
    for (;;) {
        /* input */

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* output */



        /* blink LEDs, Turn on or off outputs, etc */
    }
}
Exemple #6
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    unsigned max_apdu = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    uint8_t invoke_id = 0;
    bool found = false;
    DATABLOCK NewData;
    int iCount = 0;
    int iType = 0;
    int iKey;

    if (((argc != 2) && (argc != 3)) || ((argc >= 2) &&
            (strcmp(argv[1], "--help") == 0))) {
        printf("%s\n", argv[0]);
        printf("Usage: %s server local-device-instance\r\n       or\r\n"
            "       %s remote-device-instance\r\n",
            filename_remove_path(argv[0]), filename_remove_path(argv[0]));
        if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
            printf("\r\nServer mode:\r\n\r\n"
                "local-device-instance determins the device id of the application\r\n"
                "when running as the server end of a test set up.\r\n\r\n"
                "Non server:\r\n\r\n"
                "remote-device-instance indicates the device id of the server\r\n"
                "instance of the application.\r\n"
                "The non server application will write a series of blocks to the\r\n"
                "server and then retrieve them for display locally\r\n"
                "First it writes all 8 blocks plus a 9th which should trigger\r\n"
                "an out of range error response. Then it reads all the blocks\r\n"
                "including the ninth and finally it repeats the read operation\r\n"
                "with some deliberate errors to trigger a nack response\r\n");
        }
        return 0;
    }
    /* decode the command line parameters */
    if (_stricmp(argv[1], "server") == 0)
        Target_Mode = 1;
    else
        Target_Mode = 0;

    Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);

    if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
        fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
            Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
        return 1;
    }

    /* setup my info */
    if (Target_Mode)
        Device_Set_Object_Instance_Number(Target_Device_Object_Instance);
    else
        Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);

    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();

    if (Target_Mode) {
        printf("Entering server mode. press q to quit program\r\n\r\n");

        for (;;) {
            /* increment timer - exit if timed out */
            current_seconds = time(NULL);
            if (current_seconds != last_seconds) {
            }

            /* returns 0 bytes on timeout */
            pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

            /* process */
            if (pdu_len) {
                npdu_handler(&src, &Rx_Buf[0], pdu_len);
            }
            /* at least one second has passed */
            if (current_seconds != last_seconds) {
                putchar('.');   /* Just to show that time is passing... */
                last_seconds = current_seconds;
                tsm_timer_milliseconds(((current_seconds -
                            last_seconds) * 1000));
            }

            if (_kbhit()) {
                iKey = toupper(_getch());
                if (iKey == 'Q') {
                    printf("\r\nExiting program now\r\n");
                    exit(0);
                }
            }
        }
    } else {

        /* try to bind with the device */
        found =
            address_bind_request(Target_Device_Object_Instance, &max_apdu,
            &Target_Address);
        if (!found) {
            Send_WhoIs(Target_Device_Object_Instance,
                Target_Device_Object_Instance);
        }
        /* loop forever */
        for (;;) {
            /* increment timer - exit if timed out */
            current_seconds = time(NULL);

            /* returns 0 bytes on timeout */
            pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

            /* process */
            if (pdu_len) {
                npdu_handler(&src, &Rx_Buf[0], pdu_len);
            }
            /* at least one second has passed */
            if (current_seconds != last_seconds)
                tsm_timer_milliseconds(((current_seconds -
                            last_seconds) * 1000));
            if (Error_Detected)
                break;
            /* wait until the device is bound, or timeout and quit */
            if (!found)
                found =
                    address_bind_request(Target_Device_Object_Instance,
                    &max_apdu, &Target_Address);
            if (found) {
                if (invoke_id == 0) {   /* Safe to send a new request */
                    switch (iType) {
                        case 0:        /* Write blocks to server */
                            NewData.cMyByte1 = iCount;
                            NewData.cMyByte2 = 255 - iCount;
                            NewData.fMyReal = (float) iCount;
                            strcpy((char*)NewData.sMyString, "Test Data - [x]");
                            NewData.sMyString[13] = 'a' + iCount;
                            printf("Sending block %d\n", iCount);
                            invoke_id =
                                Send_Private_Transfer_Request
                                (Target_Device_Object_Instance,
                                BACNET_VENDOR_ID, 1, iCount, &NewData);
                            break;

                        case 1:        /* Read blocks from server */
                            printf("Requesting block %d\n", iCount);
                            invoke_id =
                                Send_Private_Transfer_Request
                                (Target_Device_Object_Instance,
                                BACNET_VENDOR_ID, 0, iCount, &NewData);
                            break;

                        case 2:        /* Generate some error responses */
                            switch (iCount) {
                                case 0:        /* Bad service number i.e. 2 */
                                case 2:
                                case 4:
                                case 6:
                                case 8:
                                    printf
                                        ("Requesting block %d with bad service number\n",
                                        iCount);
                                    invoke_id =
                                        Send_Private_Transfer_Request
                                        (Target_Device_Object_Instance,
                                        BACNET_VENDOR_ID, 2, iCount, &NewData);
                                    break;

                                case 1:        /* Bad vendor ID number */
                                case 3:
                                case 5:
                                case 7:
                                    printf
                                        ("Requesting block %d with invalid Vendor ID\n",
                                        iCount);
                                    invoke_id =
                                        Send_Private_Transfer_Request
                                        (Target_Device_Object_Instance,
                                        BACNET_VENDOR_ID + 1, 0, iCount,
                                        &NewData);
                                    break;
                            }

                            break;
                    }
                } else if (tsm_invoke_id_free(invoke_id)) {
                    if (iCount != MY_MAX_BLOCK) {
                        iCount++;
                        invoke_id = 0;
                    } else {
                        iType++;
                        iCount = 0;
                        invoke_id = 0;

                        if (iType > 2)
                            break;
                    }
                } else if (tsm_invoke_id_failed(invoke_id)) {
                    fprintf(stderr, "\rError: TSM Timeout!\r\n");
                    tsm_free_invoke_id(invoke_id);
                    Error_Detected = true;
                    /* try again or abort? */
                    break;
                }
            } else {
                /* increment timer - exit if timed out */
                elapsed_seconds += (current_seconds - last_seconds);
                if (elapsed_seconds > timeout_seconds) {
                    printf("\rError: APDU Timeout!\r\n");
                    Error_Detected = true;
                    break;
                }
            }
            /* keep track of time for next check */
            last_seconds = current_seconds;
        }
    }
    if (Error_Detected)
        return 1;
    return 0;
}
Exemple #7
0
bool Device_Write_Property_Local(
    BACNET_WRITE_PROPERTY_DATA * wp_data)
{
    bool status = false;        /* return value - false=error */
    int len = 0;
    uint8_t encoding = 0;
    size_t length = 0;
    BACNET_APPLICATION_DATA_VALUE value;

    /* decode the some of the request */
    len =
        bacapp_decode_application_data(wp_data->application_data,
        wp_data->application_data_len, &value);
    /* FIXME: len < application_data_len: more data? */
    if (len < 0) {
        /* error while decoding - a value larger than we can handle */
        wp_data->error_class = ERROR_CLASS_PROPERTY;
        wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
        return false;
    }
    if ((wp_data->object_property != PROP_OBJECT_LIST) &&
        (wp_data->array_index != BACNET_ARRAY_ALL)) {
        /*  only array properties can have array options */
        wp_data->error_class = ERROR_CLASS_PROPERTY;
        wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
        return false;
    }
    switch ((int) wp_data->object_property) {
        case PROP_OBJECT_IDENTIFIER:
            if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
                if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
                    (Device_Set_Object_Instance_Number(value.type.
                            Object_Id.instance))) {
                    /* we could send an I-Am broadcast to let the world know */
                    status = true;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_MAX_INFO_FRAMES:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if (value.type.Unsigned_Int <= 255) {
                    dlmstp_set_max_info_frames(value.type.Unsigned_Int);
                    status = true;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_MAX_MASTER:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if ((value.type.Unsigned_Int > 0) &&
                    (value.type.Unsigned_Int <= 127)) {
                    dlmstp_set_max_master(value.type.Unsigned_Int);
                    status = true;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_OBJECT_NAME:
            if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
                length = characterstring_length(&value.type.Character_String);
                if (length < 1) {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                } else if (length < characterstring_capacity(&My_Object_Name)) {
                    encoding =
                        characterstring_encoding(&value.type.Character_String);
                    if (encoding < MAX_CHARACTER_STRING_ENCODING) {
                        /* All the object names in a device must be unique. */
                        if (Device_Valid_Object_Name(&value.type.
                                Character_String, NULL, NULL)) {
                            wp_data->error_class = ERROR_CLASS_PROPERTY;
                            wp_data->error_code = ERROR_CODE_DUPLICATE_NAME;
                        } else {
                            Device_Set_Object_Name(&value.type.
                                Character_String);
                            status = true;
                        }
                    } else {
                        wp_data->error_class = ERROR_CLASS_PROPERTY;
                        wp_data->error_code =
                            ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
                    }
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code =
                        ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
                }
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case 9600:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if (value.type.Unsigned_Int <= 115200) {
                    RS485_Set_Baud_Rate(value.type.Unsigned_Int);
                    status = true;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_NUMBER_OF_APDU_RETRIES:
        case PROP_APDU_TIMEOUT:
        case PROP_VENDOR_IDENTIFIER:
        case PROP_SYSTEM_STATUS:
        case PROP_LOCATION:
        case PROP_DESCRIPTION:
        case PROP_MODEL_NAME:
        case PROP_VENDOR_NAME:
        case PROP_FIRMWARE_REVISION:
        case PROP_APPLICATION_SOFTWARE_VERSION:
        case PROP_LOCAL_TIME:
        case PROP_UTC_OFFSET:
        case PROP_LOCAL_DATE:
        case PROP_DAYLIGHT_SAVINGS_STATUS:
        case PROP_PROTOCOL_VERSION:
        case PROP_PROTOCOL_REVISION:
        case PROP_PROTOCOL_SERVICES_SUPPORTED:
        case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
        case PROP_OBJECT_LIST:
        case PROP_MAX_APDU_LENGTH_ACCEPTED:
        case PROP_SEGMENTATION_SUPPORTED:
        case PROP_DEVICE_ADDRESS_BINDING:
        case PROP_DATABASE_REVISION:
        case PROP_ACTIVE_COV_SUBSCRIPTIONS:
            wp_data->error_class = ERROR_CLASS_PROPERTY;
            wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
            break;
        default:
            wp_data->error_class = ERROR_CLASS_PROPERTY;
            wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
            break;
    }
    /* not using len at this time */
    len = len;

    return status;
}
Exemple #8
0
/** Main function of server demo.
 *
 * @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am,
 *      datalink_receive, npdu_handler,
 *      dcc_timer_seconds, bvlc_maintenance_timer,
 *      Load_Control_State_Machine_Handler, handler_cov_task,
 *      tsm_timer_milliseconds
 *
 * @param argc [in] Arg count.
 * @param argv [in] Takes one argument: the Device Instance #.
 * @return 0 on success.
 */
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 1;       /* milliseconds */
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    uint32_t elapsed_seconds = 0;
    uint32_t elapsed_milliseconds = 0;
    uint32_t address_binding_tmr = 0;
    uint32_t recipient_scan_tmr = 0;
#if defined(BAC_UCI)
    int uciId = 0;
    struct uci_context *ctx;
#endif
    int argi = 0;
    char *filename = NULL;

    filename = filename_remove_path(argv[0]);
    for (argi = 1; argi < argc; argi++) {
        if (strcmp(argv[argi], "--help") == 0) {
            print_usage(filename);
            print_help(filename);
            return 0;
        }
        if (strcmp(argv[argi], "--version") == 0) {
            printf("%s %s\n", filename, BACNET_VERSION_TEXT);
            printf("Copyright (C) 2014 by Steve Karg and others.\n"
                "This is free software; see the source for copying conditions.\n"
                "There is NO warranty; not even for MERCHANTABILITY or\n"
                "FITNESS FOR A PARTICULAR PURPOSE.\n");
            return 0;
        }
    }
#if defined(BAC_UCI)
    ctx = ucix_init("bacnet_dev");
    if (!ctx)
        fprintf(stderr, "Failed to load config file bacnet_dev\n");
    uciId = ucix_get_option_int(ctx, "bacnet_dev", "0", "Id", 0);
    printf("ID: %i", uciId);
    if (uciId != 0) {
        Device_Set_Object_Instance_Number(uciId);
    } else {
#endif /* defined(BAC_UCI) */
        /* allow the device ID to be set */
        if (argc > 1) {
            Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
        }
        if (argc > 2) {
            Device_Object_Name_ANSI_Init(argv[2]);
        }
#if defined(BAC_UCI)
    }
    ucix_cleanup(ctx);
#endif /* defined(BAC_UCI) */

    printf("BACnet Server Demo\n" "BACnet Stack Version %s\n"
        "BACnet Device ID: %u\n" "Max APDU: %d\n", BACnet_Version,
        Device_Object_Instance_Number(), MAX_APDU);
    /* load any static address bindings to show up
       in our device bindings list */
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    /* broadcast an I-Am on startup */
    Send_I_Am(&Handler_Transmit_Buffer[0]);
    /* loop forever */
    for (;;) {
        /* input */
        current_seconds = time(NULL);

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* at least one second has passed */
        elapsed_seconds = (uint32_t) (current_seconds - last_seconds);
        if (elapsed_seconds) {
            last_seconds = current_seconds;
            dcc_timer_seconds(elapsed_seconds);
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
            dlenv_maintenance_timer(elapsed_seconds);
            Load_Control_State_Machine_Handler();
            elapsed_milliseconds = elapsed_seconds * 1000;
            handler_cov_timer_seconds(elapsed_seconds);
            tsm_timer_milliseconds(elapsed_milliseconds);
            trend_log_timer(elapsed_seconds);
#if defined(INTRINSIC_REPORTING)
            Device_local_reporting();
#endif
        }
        handler_cov_task();
        /* scan cache address */
        address_binding_tmr += elapsed_seconds;
        if (address_binding_tmr >= 60) {
            address_cache_timer(address_binding_tmr);
            address_binding_tmr = 0;
        }
#if defined(INTRINSIC_REPORTING)
        /* try to find addresses of recipients */
        recipient_scan_tmr += elapsed_seconds;
        if (recipient_scan_tmr >= NC_RESCAN_RECIPIENTS_SECS) {
            Notification_Class_find_recipient();
            recipient_scan_tmr = 0;
        }
#endif
        /* output */

        /* blink LEDs, Turn on or off outputs, etc */
    }

    return 0;
}
Exemple #9
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    time_t rawtime;
    struct tm *my_time;
    BACNET_DATE bdate;
    BACNET_TIME btime;

    /* FIXME: we could send directed time sync, and how do we send UTC? */
#if 0
    if (argc < 2) {
        printf("Usage: %s date time [device-instance]\r\n"
            "Send BACnet TimeSynchronization request to all devices.\r\n"
            "date format: year/month/day:dayofweek (e.g. 2006/4/1:6)\r\n"
            "year: AD, such as 2006\r\n" "month: 1=January, 12=December\r\n"
            "day: 1-31\r\n" "dayofweek: 1=Monday, 7=Sunday\r\n" "\r\n"
            "time format: hour:minute:second.hundredths (e.g. 23:59:59.12)\r\n"
            "hour: 0-23\r\n" "minute: 0-59\r\n" "second: 0-59\r\n"
            "hundredths: 0-99\r\n" "\r\n"
            "Optional device-instance sends a unicast time sync.\r\n",
            filename_remove_path(argv[0]));
        return 0;
    }
#else
    (void) argc;
    (void) argv;
#endif
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = apdu_timeout() / 1000;
    /* send the request */
    time(&rawtime);
    my_time = localtime(&rawtime);
    bdate.year = my_time->tm_year + 1900;
    bdate.month = my_time->tm_mon + 1;
    bdate.day = my_time->tm_mday;
    bdate.wday = my_time->tm_wday ? my_time->tm_wday : 7;
    btime.hour = my_time->tm_hour;
    btime.min = my_time->tm_min;
    btime.sec = my_time->tm_sec;
    btime.hundredths = 0;
    Send_TimeSync(&bdate, &btime);
    /* loop forever - not necessary for time sync, but we can watch */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);
        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        if (Error_Detected)
            break;
        /* increment timer - exit if timed out */
        elapsed_seconds += (current_seconds - last_seconds);
        if (elapsed_seconds > timeout_seconds)
            break;
        /* keep track of time for next check */
        last_seconds = current_seconds;
    }

    return 0;
}
Exemple #10
0
bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA * wp_data)
{
    bool status = false;        /* return value - false=error */
    int len = 0;
    BACNET_APPLICATION_DATA_VALUE value;
    uint8_t max_master = 0;

    /* decode the some of the request */
    len =
        bacapp_decode_application_data(wp_data->application_data,
        wp_data->application_data_len, &value);
    /* FIXME: len < application_data_len: more data? */
    if (len < 0) {
        /* error while decoding - a value larger than we can handle */
        wp_data->error_class = ERROR_CLASS_PROPERTY;
        wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
        return false;
    }
    if ((wp_data->object_property != PROP_OBJECT_LIST) &&
        (wp_data->array_index != BACNET_ARRAY_ALL)) {
        /*  only array properties can have array options */
        wp_data->error_class = ERROR_CLASS_PROPERTY;
        wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
        return false;
    }
    switch ((int) wp_data->object_property) {
        case PROP_OBJECT_IDENTIFIER:
            if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
                if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
                    (Device_Set_Object_Instance_Number(value.type.Object_Id.
                            instance))) {
                    nvm_write(NVM_DEVICE_0,
                        (uint8_t *) & value.type.Object_Id.instance, 4);
                    /* we could send an I-Am broadcast to let the world know */
                    status = true;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_MAX_INFO_FRAMES:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if (value.type.Unsigned_Int <= 255) {
                    dlmstp_set_max_info_frames(value.type.Unsigned_Int);
                    status = true;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_MAX_MASTER:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if ((value.type.Unsigned_Int > 0) &&
                    (value.type.Unsigned_Int <= 127)) {
                    max_master = value.type.Unsigned_Int;
                    dlmstp_set_max_master(max_master);
                    nvm_write(NVM_MAX_MASTER, &max_master, 1);
                    status = true;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_OBJECT_NAME:
            if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
                status =
                    bacnet_name_write_unique(NVM_DEVICE_NAME,
                    wp_data->object_type, wp_data->object_instance,
                    &value.type.Character_String, &wp_data->error_class,
                    &wp_data->error_code);
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_DESCRIPTION:
            if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
                status =
                    bacnet_name_write(NVM_DEVICE_DESCRIPTION,
                    &value.type.Character_String, &wp_data->error_class,
                    &wp_data->error_code);
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_LOCATION:
            if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
                status =
                    bacnet_name_write(NVM_DEVICE_LOCATION,
                    &value.type.Character_String, &wp_data->error_class,
                    &wp_data->error_code);
            } else {
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_OBJECT_TYPE:
        case PROP_VENDOR_NAME:
        case PROP_FIRMWARE_REVISION:
        case PROP_APPLICATION_SOFTWARE_VERSION:
        case PROP_DAYLIGHT_SAVINGS_STATUS:
        case PROP_PROTOCOL_VERSION:
        case PROP_PROTOCOL_REVISION:
        case PROP_PROTOCOL_SERVICES_SUPPORTED:
        case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
        case PROP_OBJECT_LIST:
        case PROP_MAX_APDU_LENGTH_ACCEPTED:
        case PROP_SEGMENTATION_SUPPORTED:
        case PROP_DEVICE_ADDRESS_BINDING:
        case PROP_DATABASE_REVISION:
        case 512:
        case 513:
            wp_data->error_class = ERROR_CLASS_PROPERTY;
            wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
            break;
        default:
            wp_data->error_class = ERROR_CLASS_PROPERTY;
            wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
            break;
    }

    return status;
}
Exemple #11
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    unsigned max_apdu = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    uint8_t invoke_id = 0;
    bool found = false;
    BACNET_READ_RANGE_DATA Request;
    int iCount = 0;
    int iType = 0;
    int iKey;
    int iSecondsRun = 0;


    if (((argc != 2) && (argc != 3)) || ((argc >= 2) &&
            (strcmp(argv[1], "--help") == 0))) {
        printf("%s\n", argv[0]);
        printf("Usage: %s server local-device-instance\r\n       or\r\n"
            "       %s remote-device-instance\r\n"
            "--help gives further information\r\n",
            filename_remove_path(argv[0]), filename_remove_path(argv[0]));
        if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
            printf("\r\nServer mode:\r\n\r\n"
                "<local-device-instance> determins the device id of the application\r\n"
                "when running as the server end of a test set up. The Server simply\r\n"
                "returns dummy data for each ReadRange request\r\n\r\n"
                "Non server:\r\n\r\n"
                "<remote-device-instance> indicates the device id of the server\r\n"
                "instance of the application.\r\n"
                "The non server application will send a series of ReadRange requests to the\r\n"
                "server with examples of different range types.\r\n");
        }
        return 0;
    }
    /* decode the command line parameters */
    if (_stricmp(argv[1], "server") == 0)
        Target_Mode = 1;
    else
        Target_Mode = 0;

    Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);

    if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
        fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
            Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
        return 1;
    }

    /* setup my info */
    if (Target_Mode)
        Device_Set_Object_Instance_Number(Target_Device_Object_Instance);
    else
        Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);

    Init_Objects();
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();

    if (Target_Mode) {
#if defined(WIN32) || defined(__BORLANDC__)
        printf("Entering server mode. press q to quit program\r\n\r\n");
#else
        printf("Entering server mode.\r\n\r\n");
#endif
        for (;;) {
            /* increment timer - exit if timed out */
            current_seconds = time(NULL);

            /* returns 0 bytes on timeout */
            pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

            /* process */
            if (pdu_len) {
                npdu_handler(&src, &Rx_Buf[0], pdu_len);
            }
            /* at least one second has passed */
            if (current_seconds != last_seconds) {
                putchar('.');   /* Just to show that time is passing... */
                tsm_timer_milliseconds(((current_seconds -
                            last_seconds) * 1000));
                address_cache_timer(current_seconds - last_seconds);
                trend_log_timer(current_seconds - last_seconds);
                last_seconds = current_seconds;
                /* Change the analog input PVs for testing purposes */
                for (iCount = 0; iCount < Analog_Input_Count(); iCount++) {
                    Analog_Input_Present_Value_Set(iCount,
                        iSecondsRun * (iCount + 1));
                }

                iSecondsRun++;
            }
#if defined(WIN32) || defined(__BORLANDC__)
            if (_kbhit()) {
                iKey = toupper(_getch());
                if (iKey == 'Q') {
                    printf("\r\nExiting program now\r\n");
                    exit(0);
                }
            }
#endif
        }
    } else {

        /* try to bind with the device */
        found =
            address_bind_request(Target_Device_Object_Instance, &max_apdu,
            &Target_Address);
        if (!found) {
            Send_WhoIs(Target_Device_Object_Instance,
                Target_Device_Object_Instance);
        }
        /* loop forever */
        for (;;) {
            /* increment timer - exit if timed out */
            current_seconds = time(NULL);

            /* returns 0 bytes on timeout */
            pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

            /* process */
            if (pdu_len) {
                npdu_handler(&src, &Rx_Buf[0], pdu_len);
            }
            /* at least one second has passed */
            if (current_seconds != last_seconds) {
                tsm_timer_milliseconds(((current_seconds -
                            last_seconds) * 1000));
                address_cache_timer(current_seconds - last_seconds);
                trend_log_timer(current_seconds - last_seconds);
                last_seconds = current_seconds;
            }
            if (Error_Detected)
                break;
            /* wait until the device is bound, or timeout and quit */
            if (!found)
                found =
                    address_bind_request(Target_Device_Object_Instance,
                    &max_apdu, &Target_Address);
            if (found) {
                if (invoke_id == 0) {   /* Safe to send a new request */
                    switch (iCount) {
                        case 0:        /* Pass - should read up to 1st 10 */
                            Request.RequestType = RR_BY_POSITION;
                            Request.Range.RefIndex = 1;
                            Request.Count = 10;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;

                        case 1:        /* Pass - should read entries 2 and 3 */
                            Request.RequestType = RR_BY_POSITION;
                            Request.Range.RefSeqNum = 3;
                            Request.Count = -2;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;

                        case 2:        /* Fail - By Time not supported */
                            Request.RequestType = RR_BY_TIME;
                            Request.Range.RefTime.date.year = 2009;
                            Request.Range.RefTime.date.month = 9;
                            Request.Range.RefTime.date.day = 23;
                            Request.Range.RefTime.date.wday = 0xFF;
                            Request.Range.RefTime.time.hour = 22;
                            Request.Range.RefTime.time.min = 23;
                            Request.Range.RefTime.time.sec = 24;
                            Request.Range.RefTime.time.hundredths = 0;

                            Request.Count = 10;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;

                        case 3:        /* Fail - array not supported */
                            Request.RequestType = RR_BY_POSITION;
                            Request.Range.RefIndex = 1;
                            Request.Count = 10;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 1;
                            break;

                        case 4:        /* Fail - By Sequence not supported */
                            Request.RequestType = RR_BY_SEQUENCE;
                            Request.Range.RefSeqNum = 1;
                            Request.Count = 10;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;

                        case 5:        /* Fail Bytime not supported and array not supported */
                            Request.RequestType = RR_BY_TIME;
                            Request.Range.RefTime.date.year = 2009;
                            Request.Range.RefTime.date.month = 9;
                            Request.Range.RefTime.date.day = 23;
                            Request.Range.RefTime.date.wday = 0xFF;     /* Day of week unspecified */
                            Request.Range.RefTime.time.hour = 22;
                            Request.Range.RefTime.time.min = 23;
                            Request.Range.RefTime.time.sec = 24;
                            Request.Range.RefTime.time.hundredths = 0;

                            Request.Count = 10;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 1;
                            break;

                        case 6:        /* Pass - should try to return all entries */
                            Request.RequestType = RR_READ_ALL;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;

                        case 7:        /* Fail - array not supported */
                            Request.RequestType = RR_READ_ALL;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 1;
                            break;

                        case 8:        /* Pass - should read 1st 1 */
                            Request.RequestType = RR_BY_POSITION;
                            Request.Range.RefIndex = 1;
                            Request.Count = 1;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;

                        case 9:        /* Pass - should read 1st 2 */
                            Request.RequestType = RR_BY_POSITION;
                            Request.Range.RefIndex = 1;
                            Request.Count = 2;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;

                        case 10:       /* Pass - should read 2nd and 3rd */
                            Request.RequestType = RR_BY_POSITION;
                            Request.Range.RefIndex = 2;
                            Request.Count = 2;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;

                        case 11:       /* Pass - should read 2nd up to 11th */
                            Request.RequestType = RR_BY_POSITION;
                            Request.Range.RefIndex = 2;
                            Request.Count = 10;
                            Request.object_type = OBJECT_DEVICE;
                            Request.object_instance =
                                Target_Device_Object_Instance;
                            Request.object_property =
                                PROP_DEVICE_ADDRESS_BINDING;
                            Request.array_index = 0;
                            break;
                    }

                    invoke_id =
                        Send_ReadRange_Request(Target_Device_Object_Instance,
                        &Request);
                } else if (tsm_invoke_id_free(invoke_id)) {
                    if (iCount != 11) {
                        iCount++;
                        invoke_id = 0;
                    } else {
                        break;
                    }
                } else if (tsm_invoke_id_failed(invoke_id)) {
                    fprintf(stderr, "\rError: TSM Timeout!\r\n");
                    tsm_free_invoke_id(invoke_id);
                    /* Error_Detected = true; */
                    /* try again or abort? */
                    invoke_id = 0;      /* Try next operation */
                    /* break; */
                }
            } else {
                /* increment timer - exit if timed out */
                elapsed_seconds += (current_seconds - last_seconds);
                if (elapsed_seconds > timeout_seconds) {
                    printf("\rError: APDU Timeout!\r\n");
                    /* Error_Detected = true;
                       break; */
                    invoke_id = 0;
                }
            }
            /* keep track of time for next check */
            last_seconds = current_seconds;
        }
    }

    if (Error_Detected)
        return 1;
    return 0;
}
Exemple #12
0
/** Main function of server demo.
 *
 * @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am,
 *      datalink_receive, npdu_handler,
 *      dcc_timer_seconds, bvlc_maintenance_timer,
 *      handler_cov_task,
 *      tsm_timer_milliseconds
 *
 * @param argc [in] Arg count.
 * @param argv [in] Takes one argument: the Device Instance #.
 * @return 0 on success.
 */
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 1;       /* milliseconds */
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    uint32_t elapsed_seconds = 0;
    uint32_t elapsed_milliseconds = 0;
    uint32_t address_binding_tmr = 0;
        
    /* allow the device ID to be set */
    if (argc > 1) {
        Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
    }
    printf("BACnet Raspberry Pi PiFace Digital Demo\n" 
        "BACnet Stack Version %s\n"
        "BACnet Device ID: %u\n" 
        "Max APDU: %d\n", BACnet_Version,
        Device_Object_Instance_Number(), MAX_APDU);
    /* load any static address bindings to show up
       in our device bindings list */
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    piface_init();
    atexit(piface_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    /* broadcast an I-Am on startup */
    Send_I_Am(&Handler_Transmit_Buffer[0]);
    /* loop forever */
    for (;;) {
        /* input */
        current_seconds = time(NULL);

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* at least one second has passed */
        elapsed_seconds = (uint32_t) (current_seconds - last_seconds);
        if (elapsed_seconds) {
            last_seconds = current_seconds;
            dcc_timer_seconds(elapsed_seconds);
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
            dlenv_maintenance_timer(elapsed_seconds);
            elapsed_milliseconds = elapsed_seconds * 1000;
            handler_cov_timer_seconds(elapsed_seconds);
            tsm_timer_milliseconds(elapsed_milliseconds);
        }
        handler_cov_task();
        /* scan cache address */
        address_binding_tmr += elapsed_seconds;
        if (address_binding_tmr >= 60) {
            address_cache_timer(address_binding_tmr);
            address_binding_tmr = 0;
        }
        /* output/input */
        piface_task();
    }

    return 0;
}
Exemple #13
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = { 0 }; /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    unsigned count = 0; /* milliseconds */
    time_t start_time;
    time_t new_time = 0;

    start_time = time(NULL);    /* get current time */
    /* Linux specials */
    signal(SIGINT, sig_handler);
    signal(SIGHUP, sig_handler);
    signal(SIGTERM, sig_handler);
    /* setup this BACnet Server device */
    Device_Set_Object_Instance_Number(111);
    Init_Service_Handlers();
    dlenv_init();
    /* loop forever */
    for (;;) {
        /* input */
        new_time = time(NULL);
        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        if (new_time > start_time) {
            tsm_timer_milliseconds(new_time - start_time * 1000);
            start_time = new_time;
        }
        if (I_Am_Request) {
            I_Am_Request = false;
            Send_I_Am(&Handler_Transmit_Buffer[0]);
        } else if (Who_Is_Request) {
            Who_Is_Request = false;
            Send_WhoIs(-1, -1);
        }
        /* output */
        /* some round robin task switching */
        count++;
        switch (count) {
            case 1:
                /* used for testing, but kind of noisy on the network */
                /*Read_Properties(); */
                break;
            case 2:
                break;
            default:
                count = 0;
                break;
        }

        /* blink LEDs, Turn on or off outputs, etc */
    }

    return 0;
}
Exemple #14
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 10;      /* milliseconds */
    unsigned max_apdu = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    time_t delta_seconds = 0;
    bool found = false;
    char *filename = NULL;
    char *value_string = NULL;
    bool status = false;
    int args_remaining = 0, tag_value_arg = 0, i = 0;
    BACNET_APPLICATION_TAG property_tag;
    uint8_t context_tag = 0;
    BACNET_PRIVATE_TRANSFER_DATA private_data = { 0 };
    int len = 0;
    bool sent_message = false;

    if (argc < 6) {
        filename = filename_remove_path(argv[0]);
        printf("Usage: %s <device-instance|broadcast|dnet=> vendor-id"
            " service-number tag value [tag value...]\r\n", filename);
        if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
            printf("device-instance:\r\n"
                "BACnet Device Object Instance number that you are\r\n"
                "trying to communicate to.  This number will be used\r\n"
                "to try and bind with the device using Who-Is and\r\n"
                "I-Am services.  For example, if you were transferring to\r\n"
                "Device Object 123, the device-instance would be 123.\r\n"
                "For Global Broadcast, use the word 'broadcast'.\r\n"
                "For Local Broadcast to a particular DNET n, use 'dnet=n'.\r\n"
                "\r\n" "vendor_id:\r\n"
                "the unique vendor identification code for the type of\r\n"
                "vendor proprietary service to be performed.\r\n" "\r\n"
                "service-number (Unsigned32):\r\n"
                "the desired proprietary service to be performed.\r\n" "\r\n"
                "tag:\r\n" "Tag is the integer value of the enumeration \r\n"
                "BACNET_APPLICATION_TAG in bacenum.h.\r\n"
                "It is the data type of the value that you are sending.\r\n"
                "For example, if you were transfering a REAL value, you would \r\n"
                "use a tag of 4.\r\n"
                "Context tags are created using two tags in a row.\r\n"
                "The context tag is preceded by a C.  Ctag tag.\r\n"
                "C2 4 creates a context 2 tagged REAL.\r\n" "\r\n" "value:\r\n"
                "The value is an ASCII representation of some type of data\r\n"
                "that you are transfering.\r\n"
                "It is encoded using the tag information provided.\r\n"
                "For example, if you were transferring a REAL value of 100.0,\r\n"
                "you would use 100.0 as the value.\r\n"
                "If you were transferring an object identifier for Device 123,\r\n"
                "you would use 8:123 as the value.\r\n" "\r\n" "Example:\r\n"
                "If you want to transfer a REAL value of 1.1 to service 23 of \r\n"
                "vendor 260 in Device 99, you could send the following command:\r\n"
                "%s 99 260 23 4 1.1\r\n", filename);
        }
        return 0;
    }
    /* decode the command line parameters */
    if (strcmp(argv[1], "broadcast") == 0) {
        Target_Broadcast = true;
        Target_DNET = BACNET_BROADCAST_NETWORK;
    } else if (strncmp(argv[1], "dnet=", 5) == 0) {
        Target_Broadcast = true;
        Target_DNET = strtol(&argv[1][5], NULL, 0);
    } else {
        Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
    }
    Target_Vendor_Identifier = strtol(argv[2], NULL, 0);
    Target_Service_Number = strtol(argv[3], NULL, 0);
    if ((!Target_Broadcast) &&
        (Target_Device_Object_Instance > BACNET_MAX_INSTANCE)) {
        fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
            Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
        return 1;
    }
    args_remaining = (argc - (6 - 2));
    for (i = 0; i < MAX_PROPERTY_VALUES; i++) {
        tag_value_arg = (6 - 2) + (i * 2);
        /* special case for context tagged values */
        if (toupper(argv[tag_value_arg][0]) == 'C') {
            context_tag = strtol(&argv[tag_value_arg][1], NULL, 0);
            tag_value_arg++;
            args_remaining--;
            Target_Object_Property_Value[i].context_tag = context_tag;
            Target_Object_Property_Value[i].context_specific = true;
        } else {
            Target_Object_Property_Value[i].context_specific = false;
        }
        property_tag = strtol(argv[tag_value_arg], NULL, 0);
        args_remaining--;
        if (args_remaining <= 0) {
            fprintf(stderr, "Error: not enough tag-value pairs\r\n");
            return 1;
        }
        value_string = argv[tag_value_arg + 1];
        args_remaining--;
        /* printf("tag[%d]=%u value[%d]=%s\r\n",
           i, property_tag, i, value_string); */
        if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
            fprintf(stderr, "Error: tag=%u - it must be less than %u\r\n",
                property_tag, MAX_BACNET_APPLICATION_TAG);
            return 1;
        }
        status =
            bacapp_parse_application_data(property_tag, value_string,
            &Target_Object_Property_Value[i]);
        if (!status) {
            /* FIXME: show the expected entry format for the tag */
            fprintf(stderr, "Error: unable to parse the tag value\r\n");
            return 1;
        }
        Target_Object_Property_Value[i].next = NULL;
        if (i > 0) {
            Target_Object_Property_Value[i - 1].next =
                &Target_Object_Property_Value[i];
        }
        if (args_remaining <= 0) {
            break;
        }
    }
    if (args_remaining > 0) {
        fprintf(stderr, "Error: Exceeded %d tag-value pairs.\r\n",
            MAX_PROPERTY_VALUES);
        return 1;
    }
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    if (Target_Broadcast) {
        datalink_get_broadcast_address(&Target_Address);
        Target_Address.net = Target_DNET;
        found = true;
        timeout_seconds = 0;
    } else {
        timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
        /* try to bind with the device */
        found =
            address_bind_request(Target_Device_Object_Instance, &max_apdu,
            &Target_Address);
        if (!found) {
            Send_WhoIs(Target_Device_Object_Instance,
                Target_Device_Object_Instance);
        }
    }
    /* loop forever */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);
        /* at least one second has passed */
        if (current_seconds != last_seconds) {
            /* increment timer - exit if timed out */
            delta_seconds = current_seconds - last_seconds;
            elapsed_seconds += delta_seconds;
            tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
        }
        if (Error_Detected)
            break;
        /* wait until the device is bound, or timeout and quit */
        if (!found) {
            found =
                address_bind_request(Target_Device_Object_Instance, &max_apdu,
                &Target_Address);
        }
        if (!sent_message) {
            if (found) {
                len =
                    bacapp_encode_data(&Service_Parameters[0],
                    &Target_Object_Property_Value[0]);
                private_data.serviceParameters = &Service_Parameters[0];
                private_data.serviceParametersLen = len;
                private_data.vendorID = Target_Vendor_Identifier;
                private_data.serviceNumber = Target_Service_Number;
                Send_UnconfirmedPrivateTransfer(&Target_Address,
                    &private_data);
                printf("Sent PrivateTransfer.");
                if (timeout_seconds) {
                    printf(" Waiting %u seconds.\r\n",
                        (unsigned) (timeout_seconds - elapsed_seconds));
                } else {
                    printf("\r\n");
                }
                sent_message = true;
            } else {
                if (elapsed_seconds > timeout_seconds) {
                    printf("\rError: APDU Timeout!\r\n");
                    Error_Detected = true;
                    break;
                }
            }
        }
        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        if (Error_Detected) {
            break;
        }
        /* unconfirmed - so just wait until our timeout value */
        if (elapsed_seconds > timeout_seconds) {
            break;
        }
        /* keep track of time for next check */
        last_seconds = current_seconds;
    }

    if (Error_Detected)
        return 1;
    return 0;
}
Exemple #15
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 1;       /* milliseconds */
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    uint32_t elapsed_seconds = 0;
    uint32_t elapsed_milliseconds = 0;
    uint32_t address_binding_tmr = 0;
    uint32_t recipient_scan_tmr = 0;
    uint16_t count = 0;

    /* allow the device ID to be set */
    if (argc > 1)
        Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
    printf("BACnet Server Demo\n" "BACnet Stack Version %s\n"
        "BACnet Device ID: %u\n" "Max APDU: %d\n", BACnet_Version,
        Device_Object_Instance_Number(), MAX_APDU);
    /* load any static address bindings to show up
       in our device bindings list */
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    /* broadcast an I-Am on startup */
    Send_I_Am(&Handler_Transmit_Buffer[0]);

//////////////////////////////////////
	initPin(GPIO_PIN1);
	initPin(GPIO_PIN2);
	setPinDirection(GPIO_PIN1, IN);
	setPinDirection(GPIO_PIN2, IN);

  struct itimerval it_val;	/* for setting itimer */

  /* Upon SIGALRM, call DoStuff().
   * Set interval timer.  We want frequency in ms, 
   * but the setitimer call needs seconds and useconds. */
  if (signal(SIGALRM, (void (*)(int)) countPeopleInFunc) == SIG_ERR) {
    perror("Unable to catch SIGALRM");
    exit(1);
  }
/*
  if (signal(SIGALRM, (void (*)(int)) countPeopleOutFunc) == SIG_ERR) {
    perror("Unable to catch SIGALRM");
    exit(1);
  }
*/
  it_val.it_value.tv_sec =     INTERVAL/1000;
  it_val.it_value.tv_usec =    (INTERVAL*1000) % 1000000;	
  it_val.it_interval = it_val.it_value;
  if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
    perror("error calling setitimer()");
    exit(1);
  }
////////////////////////////////////////////////////



    /* loop forever */
    for (;;) {
        /* input */
        current_seconds = time(NULL);

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* at least one second has passed */
        elapsed_seconds = (uint32_t) (current_seconds - last_seconds);
        if (elapsed_seconds) {
            last_seconds = current_seconds;
            dcc_timer_seconds(elapsed_seconds);
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
            dlenv_maintenance_timer(elapsed_seconds);
            Load_Control_State_Machine_Handler();
            elapsed_milliseconds = elapsed_seconds * 1000;
            handler_cov_timer_seconds(elapsed_seconds);
            tsm_timer_milliseconds(elapsed_milliseconds);
            trend_log_timer(elapsed_seconds);
#if defined(INTRINSIC_REPORTING)
            Device_local_reporting();
#endif
        }
        handler_cov_task();
        /* scan cache address */
        address_binding_tmr += elapsed_seconds;
        if (address_binding_tmr >= 60) {
            address_cache_timer(address_binding_tmr);
            address_binding_tmr = 0;
        }
#if defined(INTRINSIC_REPORTING)
        /* try to find addresses of recipients */
        recipient_scan_tmr += elapsed_seconds;
        if (recipient_scan_tmr >= NC_RESCAN_RECIPIENTS_SECS) {
            Notification_Class_find_recipient();
            recipient_scan_tmr = 0;
        }
#endif
	
        /* output */

        /* blink LEDs, Turn on or off outputs, etc */
    }

    return 0;
}
Exemple #16
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    unsigned max_apdu = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    uint8_t invoke_id = 0;
    bool found = false;

    if (argc < 3) {
        printf("Usage: %s device-instance state timeout [password]\r\n"
            "Send BACnet DeviceCommunicationControl service to device.\r\n"
            "\r\n" "The device-instance can be 0 to %d.\r\n"
            "Possible state values:\r\n" "  0=enable\r\n" "  1=disable\r\n"
            "  2=disable-initiation\r\n"
            "The timeout can be 0 for infinite, or a value in minutes for disable.\r\n"
            "The optional password is a character string of 1 to 20 characters.\r\n"
            "Use BACNET_IFACE environment variable for the interface\r\n",
            filename_remove_path(argv[0]), BACNET_MAX_INSTANCE - 1);
        return 0;
    }
    /* decode the command line parameters */
    Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
    Communication_State = (uint16_t) strtol(argv[2], NULL, 0);
    Communication_Timeout_Minutes = (uint16_t) strtol(argv[3], NULL, 0);
    /* optional password */
    if (argc > 4)
        Communication_Password = argv[4];

    if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
        fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
            Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
        return 1;
    }

    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
    /* try to bind with the device */
    found =
        address_bind_request(Target_Device_Object_Instance, &max_apdu,
        &Target_Address);
    if (!found) {
        Send_WhoIs(Target_Device_Object_Instance,
            Target_Device_Object_Instance);
    }
    /* loop forever */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* at least one second has passed */
        if (current_seconds != last_seconds)
            tsm_timer_milliseconds((uint16_t) ((current_seconds -
                        last_seconds) * 1000));
        if (Error_Detected)
            break;
        /* wait until the device is bound, or timeout and quit */
        if (!found) {
            found =
                address_bind_request(Target_Device_Object_Instance, &max_apdu,
                &Target_Address);
        }
        if (found) {
            if (invoke_id == 0) {
                invoke_id =
                    Send_Device_Communication_Control_Request
                    (Target_Device_Object_Instance,
                    Communication_Timeout_Minutes, Communication_State,
                    Communication_Password);
            } else if (tsm_invoke_id_free(invoke_id))
                break;
            else if (tsm_invoke_id_failed(invoke_id)) {
                fprintf(stderr, "\rError: TSM Timeout!\r\n");
                tsm_free_invoke_id(invoke_id);
                /* try again or abort? */
                break;
            }
        } else {
            /* increment timer - exit if timed out */
            elapsed_seconds += (current_seconds - last_seconds);
            if (elapsed_seconds > timeout_seconds) {
                printf("\rError: APDU Timeout!\r\n");
                break;
            }
        }
        /* keep track of time for next check */
        last_seconds = current_seconds;
    }

    return 0;
}
Exemple #17
0
/** Main function of server demo.
 *
 * @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am,
 *      datalink_receive, npdu_handler,
 *      dcc_timer_seconds, bvlc_maintenance_timer,
 *      Load_Control_State_Machine_Handler, handler_cov_task,
 *      tsm_timer_milliseconds
 *
 * @param argc [in] Arg count.
 * @param argv [in] Takes one argument: the Device Instance #.
 * @return 0 on success.
 */
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 1;       /* milliseconds */
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    uint32_t elapsed_seconds = 0;
    uint32_t elapsed_milliseconds = 0;
    uint32_t address_binding_tmr = 0;
    uint32_t recipient_scan_tmr = 0;

    /* allow the device ID to be set */
    if (argc > 1)
        Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
    printf("BACnet Server Demo\n" "BACnet Stack Version %s\n"
        "BACnet Device ID: %u\n" "Max APDU: %d\n", BACnet_Version,
        Device_Object_Instance_Number(), MAX_APDU);
    /* load any static address bindings to show up
       in our device bindings list */
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    /* broadcast an I-Am on startup */
    Send_I_Am(&Handler_Transmit_Buffer[0]);
    /* loop forever */
    for (;;) {
        /* input */
        current_seconds = time(NULL);

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* at least one second has passed */
        elapsed_seconds = (uint32_t) (current_seconds - last_seconds);
        if (elapsed_seconds) {
            last_seconds = current_seconds;
            dcc_timer_seconds(elapsed_seconds);
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
            dlenv_maintenance_timer(elapsed_seconds);
            Load_Control_State_Machine_Handler();
            elapsed_milliseconds = elapsed_seconds * 1000;
            handler_cov_timer_seconds(elapsed_seconds);
            tsm_timer_milliseconds(elapsed_milliseconds);
            trend_log_timer(elapsed_seconds);
#if defined(INTRINSIC_REPORTING)
            Device_local_reporting();
#endif
        }
        handler_cov_task();
        /* scan cache address */
        address_binding_tmr += elapsed_seconds;
        if (address_binding_tmr >= 60) {
            address_cache_timer(address_binding_tmr);
            address_binding_tmr = 0;
        }
#if defined(INTRINSIC_REPORTING)
        /* try to find addresses of recipients */
        recipient_scan_tmr += elapsed_seconds;
        if (recipient_scan_tmr >= NC_RESCAN_RECIPIENTS_SECS) {
            Notification_Class_find_recipient();
            recipient_scan_tmr = 0;
        }
#endif
        /* output */

        /* blink LEDs, Turn on or off outputs, etc */
    }

    return 0;
}
Exemple #18
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    unsigned max_apdu = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    int fileStartPosition = 0;
    unsigned requestedOctetCount = 0;
    uint8_t invoke_id = 0;
    bool found = false;
    uint16_t my_max_apdu = 0;

    if (argc < 4) {
        /* FIXME: what about access method - record or stream? */
        printf("%s device-instance file-instance local-name\r\n",
            filename_remove_path(argv[0]));
        return 0;
    }
    /* decode the command line parameters */
    Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
    Target_File_Object_Instance = strtol(argv[2], NULL, 0);
    Local_File_Name = argv[3];
    if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
        fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
            Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
        return 1;
    }
    if (Target_File_Object_Instance >= BACNET_MAX_INSTANCE) {
        fprintf(stderr, "file-instance=%u - it must be less than %u\r\n",
            Target_File_Object_Instance, BACNET_MAX_INSTANCE + 1);
        return 1;
    }
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
    /* try to bind with the device */
    Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
    /* loop forever */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* at least one second has passed */
        if (current_seconds != last_seconds) {
            tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
        }
        /* wait until the device is bound, or timeout and quit */
        found =
            address_bind_request(Target_Device_Object_Instance, &max_apdu,
            &Target_Address);
        if (found) {
            /* calculate the smaller of our APDU size or theirs
               and remove the overhead of the APDU (about 16 octets max).
               note: we could fail if there is a bottle neck (router)
               and smaller MPDU in betweeen. */
            if (max_apdu < MAX_APDU) {
                my_max_apdu = max_apdu;
            } else {
                my_max_apdu = MAX_APDU;
            }
            /* Typical sizes are 50, 128, 206, 480, 1024, and 1476 octets */
            if (my_max_apdu <= 50) {
                requestedOctetCount = my_max_apdu - 20;
            } else if (my_max_apdu <= 480) {
                requestedOctetCount = my_max_apdu - 32;
            } else if (my_max_apdu <= 1476) {
                requestedOctetCount = my_max_apdu - 64;
            } else {
                requestedOctetCount = my_max_apdu / 2;
            }
            /* has the previous invoke id expired or returned?
               note: invoke ID = 0 is invalid, so it will be idle */
            if ((invoke_id == 0) || tsm_invoke_id_free(invoke_id)) {
                if (End_Of_File_Detected || Error_Detected) {
                    break;
                }
                if (invoke_id != 0) {
                    fileStartPosition += requestedOctetCount;
                }
                /* we'll read the file in chunks
                   less than max_apdu to keep unsegmented */
                invoke_id =
                    Send_Atomic_Read_File_Stream(Target_Device_Object_Instance,
                    Target_File_Object_Instance, fileStartPosition,
                    requestedOctetCount);
                Current_Invoke_ID = invoke_id;
            } else if (tsm_invoke_id_failed(invoke_id)) {
                fprintf(stderr, "\rError: TSM Timeout!\r\n");
                tsm_free_invoke_id(invoke_id);
                /* try again or abort? */
                Error_Detected = true;
                break;
            }
        } else {
            /* increment timer - exit if timed out */
            elapsed_seconds += (current_seconds - last_seconds);
            if (elapsed_seconds > timeout_seconds) {
                fprintf(stderr, "\rError: APDU Timeout!\r\n");
                Error_Detected = true;
                break;
            }
        }
        /* keep track of time for next check */
        last_seconds = current_seconds;
    }

    if (Error_Detected) {
        return 1;
    }

    return 0;
}
Exemple #19
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    time_t total_seconds = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;

    if (argc < 2) {
        printf("Usage: %s address [DNET ID Len Info]\r\n",
            filename_remove_path(argv[0]));
        return 0;
    }
    if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
        printf("Send BACnet Initialize-Routing-Table message to a network\r\n"
            "and wait for responses.  Displays their network information.\r\n"
            "\r\n" "address:\r\n"
            "MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\r\n"
            "DNET ID Len Info:\r\n" "Port-info data:\r\n" "   DNET:\r\n"
            "   Destination network number 0-65534\r\n" "   ID:\r\n"
            "   Port Identifier number 0-255\r\n" "   Info:\r\n"
            "   Octet string of data, up to 255 octets\r\n"
            "To query the complete routing table, do not include any port-info.\r\n"
            "To query using Initialize-Routing-Table message to 192.168.0.18:\r\n"
            "%s 192.168.0.18:47808\r\n", filename_remove_path(argv[0]));
        return 0;
    }
    /* decode the command line parameters */
    address_parse(&Target_Router_Address, argc - 1, &argv[1]);
    if (argc > 2) {
        /* FIXME: add port info parse */
        /* BACNET_ROUTER_PORT *router_port_list
           Target_Router_Port_List
           ports_parse(&router_port[0], argc-2, &argv[2]);
           Target_Router_Port_List = router_port[0];
         */
    }
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    Init_Service_Handlers();
    address_init();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = apdu_timeout() / 1000;
    /* send the request */
    Send_Initialize_Routing_Table(&Target_Router_Address, DNET_list);
    /* loop forever */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);
        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
        /* process */
        if (pdu_len) {
            My_NPDU_Handler(&src, &Rx_Buf[0], pdu_len);
        }
        if (Error_Detected)
            break;
        /* increment timer - exit if timed out */
        elapsed_seconds = current_seconds - last_seconds;
        if (elapsed_seconds) {
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
        }
        total_seconds += elapsed_seconds;
        if (total_seconds > timeout_seconds)
            break;
        /* keep track of time for next check */
        last_seconds = current_seconds;
    }

    return 0;
}
Exemple #20
0
void Device_Reinit(
    void)
{
    dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
}
Exemple #21
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    time_t total_seconds = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    BACNET_ADDRESS dest;
    int argi;

    /* print help if requested */
    for (argi = 1; argi < argc; argi++) {
        if (strcmp(argv[argi], "--help") == 0) {
            print_help(filename_remove_path(argv[0]));
            return 0;
        }
    }

    datalink_get_broadcast_address(&dest);

    /* decode the command line parameters */
    if (argc >= 2) {
        char *s;
        long v = strtol(argv[1], &s, 0);
        if (*s++ == ':') {
            if (argv[1][0] != ':')
                dest.net = (uint16_t) v;
            dest.mac_len = 0;
            if (isdigit(*s))
                parse_bac_address(&dest, s);
        } else {
            Target_Object_Instance_Min = Target_Object_Instance_Max = v;
        }
    }

    if (argc <= 2) {
        /* empty */
    } else if (argc == 3) {
        if (Target_Object_Instance_Min == -1)
            Target_Object_Instance_Min = Target_Object_Instance_Max =
                strtol(argv[2], NULL, 0);
        else
            Target_Object_Instance_Max = strtol(argv[2], NULL, 0);
    } else if (argc == 4) {
        Target_Object_Instance_Min = strtol(argv[2], NULL, 0);
        Target_Object_Instance_Max = strtol(argv[3], NULL, 0);
    } else {
        print_usage(filename_remove_path(argv[0]));
        return 1;
    }

    if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) {
        fprintf(stderr, "device-instance-min=%u - it must be less than %u\r\n",
            Target_Object_Instance_Min, BACNET_MAX_INSTANCE + 1);
        return 1;
    }
    if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) {
        fprintf(stderr, "device-instance-max=%u - it must be less than %u\r\n",
            Target_Object_Instance_Max, BACNET_MAX_INSTANCE + 1);
        return 1;
    }

    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    init_service_handlers();
    address_init();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = apdu_timeout() / 1000;
    /* send the request */
    Send_WhoIs_To_Network(&dest, Target_Object_Instance_Min,
        Target_Object_Instance_Max);
    /* loop forever */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);
        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        if (Error_Detected)
            break;
        /* increment timer - exit if timed out */
        elapsed_seconds = current_seconds - last_seconds;
        if (elapsed_seconds) {
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
        }
        total_seconds += elapsed_seconds;
        if (total_seconds > timeout_seconds)
            break;
        /* keep track of time for next check */
        last_seconds = current_seconds;
    }
    print_address_cache();

    return 0;
}
Exemple #22
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    unsigned max_apdu = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    bool found = false;
    char *value_string = NULL;
    bool status = false;
    int args_remaining = 0, tag_value_arg = 0, i = 0;
    BACNET_APPLICATION_TAG property_tag;
    uint8_t context_tag = 0;
    int argi = 0;

    /* print help if requested */
    for (argi = 1; argi < argc; argi++) {
        if (strcmp(argv[argi], "--help") == 0) {
            print_usage(filename_remove_path(argv[0]));
            print_help(filename_remove_path(argv[0]));
            return 0;
        }
        if (strcmp(argv[argi], "--version") == 0) {
            printf("%s %s\n",
                filename_remove_path(argv[0]),
                BACNET_VERSION_TEXT);
            printf("Copyright (C) 2014 by Steve Karg\n"
                "This is free software; see the source for copying conditions.\n"
                "There is NO warranty; not even for MERCHANTABILITY or\n"
                "FITNESS FOR A PARTICULAR PURPOSE.\n");
            return 0;
        }
    }
    if (argc < 9) {
        print_usage(filename_remove_path(argv[0]));
        return 0;
    }
    /* decode the command line parameters */
    Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
    Target_Object_Type = strtol(argv[2], NULL, 0);
    Target_Object_Instance = strtol(argv[3], NULL, 0);
    Target_Object_Property = strtol(argv[4], NULL, 0);
    Target_Object_Property_Priority = (uint8_t) strtol(argv[5], NULL, 0);
    Target_Object_Property_Index = strtol(argv[6], NULL, 0);
    if (Target_Object_Property_Index == -1)
        Target_Object_Property_Index = BACNET_ARRAY_ALL;
    if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
        fprintf(stderr, "device-instance=%u - it must be less than %u\n",
            Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1);
        return 1;
    }
    if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) {
        fprintf(stderr, "object-type=%u - it must be less than %u\n",
            Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1);
        return 1;
    }
    if (Target_Object_Instance > BACNET_MAX_INSTANCE) {
        fprintf(stderr, "object-instance=%u - it must be less than %u\n",
            Target_Object_Instance, BACNET_MAX_INSTANCE + 1);
        return 1;
    }
    if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) {
        fprintf(stderr, "property=%u - it must be less than %u\n",
            Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1);
        return 1;
    }
    args_remaining = (argc - 7);
    for (i = 0; i < MAX_PROPERTY_VALUES; i++) {
        tag_value_arg = 7 + (i * 2);
        /* special case for context tagged values */
        if (toupper(argv[tag_value_arg][0]) == 'C') {
            context_tag = (uint8_t) strtol(&argv[tag_value_arg][1], NULL, 0);
            tag_value_arg++;
            args_remaining--;
            Target_Object_Property_Value[i].context_tag = context_tag;
            Target_Object_Property_Value[i].context_specific = true;
        } else {
            Target_Object_Property_Value[i].context_specific = false;
        }
        property_tag = strtol(argv[tag_value_arg], NULL, 0);
        args_remaining--;
        if (args_remaining <= 0) {
            fprintf(stderr, "Error: not enough tag-value pairs\n");
            return 1;
        }
        value_string = argv[tag_value_arg + 1];
        args_remaining--;
        /* printf("tag[%d]=%u value[%d]=%s\n",
           i, property_tag, i, value_string); */
        if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
            fprintf(stderr, "Error: tag=%u - it must be less than %u\n",
                property_tag, MAX_BACNET_APPLICATION_TAG);
            return 1;
        }
        status =
            bacapp_parse_application_data(property_tag, value_string,
            &Target_Object_Property_Value[i]);
        if (!status) {
            /* FIXME: show the expected entry format for the tag */
            fprintf(stderr, "Error: unable to parse the tag value\n");
            return 1;
        }
        Target_Object_Property_Value[i].next = NULL;
        if (i > 0) {
            Target_Object_Property_Value[i - 1].next =
                &Target_Object_Property_Value[i];
        }
        if (args_remaining <= 0) {
            break;
        }
    }
    if (args_remaining > 0) {
        fprintf(stderr, "Error: Exceeded %d tag-value pairs.\n",
            MAX_PROPERTY_VALUES);
        return 1;
    }
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
    /* try to bind with the device */
    found =
        address_bind_request(Target_Device_Object_Instance, &max_apdu,
        &Target_Address);
    if (!found) {
        Send_WhoIs(Target_Device_Object_Instance,
            Target_Device_Object_Instance);
    }
    /* loop forever */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);

        /* at least one second has passed */
        if (current_seconds != last_seconds)
            tsm_timer_milliseconds((uint16_t) ((current_seconds -
                        last_seconds) * 1000));
        if (Error_Detected)
            break;
        /* wait until the device is bound, or timeout and quit */
        if (!found) {
            found =
                address_bind_request(Target_Device_Object_Instance, &max_apdu,
                &Target_Address);
        }
        if (found) {
            if (Request_Invoke_ID == 0) {
                Request_Invoke_ID =
                    Send_Write_Property_Request(Target_Device_Object_Instance,
                    Target_Object_Type, Target_Object_Instance,
                    Target_Object_Property, &Target_Object_Property_Value[0],
                    Target_Object_Property_Priority,
                    Target_Object_Property_Index);
            } else if (tsm_invoke_id_free(Request_Invoke_ID))
                break;
            else if (tsm_invoke_id_failed(Request_Invoke_ID)) {
                fprintf(stderr, "\rError: TSM Timeout!\n");
                tsm_free_invoke_id(Request_Invoke_ID);
                Error_Detected = true;
                /* try again or abort? */
                break;
            }
        } else {
            /* increment timer - exit if timed out */
            elapsed_seconds += (current_seconds - last_seconds);
            if (elapsed_seconds > timeout_seconds) {
                Error_Detected = true;
                printf("\rError: APDU Timeout!\n");
                break;
            }
        }

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }

        /* keep track of time for next check */
        last_seconds = current_seconds;
    }
    if (Error_Detected)
        return 1;
    return 0;
}
Exemple #23
0
bool Device_Write_Property(
    BACNET_WRITE_PROPERTY_DATA * wp_data,
    BACNET_ERROR_CLASS * error_class,
    BACNET_ERROR_CODE * error_code)
{
    bool status = false;        /* return value */
    int len = 0;
    BACNET_APPLICATION_DATA_VALUE value;

    if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) {
        *error_class = ERROR_CLASS_OBJECT;
        *error_code = ERROR_CODE_UNKNOWN_OBJECT;
        return false;
    }
    /* decode the some of the request */
    len =
        bacapp_decode_application_data(wp_data->application_data,
        wp_data->application_data_len, &value);
    /* FIXME: len < application_data_len: more data? */
    /* FIXME: len == 0: unable to decode? */
    switch (wp_data->object_property) {
        case PROP_OBJECT_IDENTIFIER:
            if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
                if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
                    (Device_Set_Object_Instance_Number(value.type.
                            Object_Id.instance))) {
                    /* we could send an I-Am broadcast to let the world know */
                    status = true;
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_MAX_INFO_FRAMES:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if (value.type.Unsigned_Int <= 255) {
                    dlmstp_set_max_info_frames(value.type.Unsigned_Int);
                    status = true;
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_MAX_MASTER:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if ((value.type.Unsigned_Int > 0) &&
                    (value.type.Unsigned_Int <= 127)) {
                    dlmstp_set_max_master(value.type.Unsigned_Int);
                    status = true;
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_OBJECT_NAME:
            if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
                uint8_t encoding;

                encoding =
                    characterstring_encoding(&value.type.Character_String);
                if (encoding == CHARACTER_ANSI_X34) {
                    if (characterstring_ansi_copy(&Object_Name[0],
                            sizeof(Object_Name),
                            &value.type.Character_String)) {
                        status = true;
                    } else {
                        *error_class = ERROR_CLASS_PROPERTY;
                        *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
                    }
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case 9600:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if (value.type.Unsigned_Int > 115200) {
                    RS485_Set_Baud_Rate(value.type.Unsigned_Int);
                    status = true;
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        default:
            *error_class = ERROR_CLASS_PROPERTY;
            *error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
            break;
    }

    return status;
}
Exemple #24
0
int main(
    int argc,
    char *argv[])
{
    BACNET_EVENT_NOTIFICATION_DATA event_data = {0};
    BACNET_BIT_STRING *pBitString;
    BACNET_CHARACTER_STRING bcstring;
    BACNET_PROPERTY_STATE_TYPE tag = BOOLEAN_VALUE;
    long dnet = -1;
    BACNET_MAC_ADDRESS mac = { 0 };
    BACNET_MAC_ADDRESS adr = { 0 };
    BACNET_ADDRESS dest = { 0 };
    bool specific_address = false;
    int argi = 0;
    unsigned int target_args = 0;
    char *filename = NULL;

    filename = filename_remove_path(argv[0]);
    for (argi = 1; argi < argc; argi++) {
        if (strcmp(argv[argi], "--help") == 0) {
            print_usage(filename);
            print_help(filename);
            return 0;
        }
        if (strcmp(argv[argi], "--version") == 0) {
            printf("%s %s\n", filename, BACNET_VERSION_TEXT);
            printf("Copyright (C) 2016 by Steve Karg and others.\n"
                "This is free software; see the source for copying conditions.\n"
                "There is NO warranty; not even for MERCHANTABILITY or\n"
                "FITNESS FOR A PARTICULAR PURPOSE.\n");
            return 0;
        }
        if (strcmp(argv[argi], "--mac") == 0) {
            if (++argi < argc) {
                if (address_mac_from_ascii(&mac, argv[argi])) {
                    specific_address = true;
                }
            }
        } else if (strcmp(argv[argi], "--dnet") == 0) {
            if (++argi < argc) {
                dnet = strtol(argv[argi], NULL, 0);
                if ((dnet >= 0) && (dnet <= BACNET_BROADCAST_NETWORK)) {
                    specific_address = true;
                }
            }
        } else if (strcmp(argv[argi], "--dadr") == 0) {
            if (++argi < argc) {
                if (address_mac_from_ascii(&adr, argv[argi])) {
                    specific_address = true;
                }
            }
        } else {
            if (target_args == 0) {
                event_data.processIdentifier = strtol(argv[argi], NULL, 0);
                target_args++;
            } else if (target_args == 1) {
                event_data.initiatingObjectIdentifier.type =
                    strtol(argv[argi], NULL, 0);
                target_args++;
            } else if (target_args == 2) {
                event_data.initiatingObjectIdentifier.instance =
                    strtol(argv[argi], NULL, 0);
                target_args++;
            } else if (target_args == 3) {
                event_data.eventObjectIdentifier.type =
                    strtol(argv[argi], NULL, 0);
                target_args++;
            } else if (target_args == 4) {
                event_data.eventObjectIdentifier.instance =
                    strtol(argv[argi], NULL, 0);
                target_args++;
            } else if (target_args == 5) {
                event_data.timeStamp.tag = TIME_STAMP_SEQUENCE;
                event_data.timeStamp.value.sequenceNum =
                    strtol(argv[argi], NULL, 0);
                target_args++;
            } else if (target_args == 6) {
                event_data.notificationClass =
                    strtol(argv[argi], NULL, 0);
                target_args++;
            } else if (target_args == 7) {
                event_data.priority = strtol(argv[argi], NULL, 0);
                target_args++;
            } else if (target_args == 8) {
                event_data.eventType = strtol(argv[argi], NULL, 0);
                target_args++;
            } else {
                if (event_data.eventType == EVENT_CHANGE_OF_BITSTRING) {
                    if (target_args == 9) {
                        pBitString = &event_data.notificationParams.changeOfBitstring.referencedBitString;
                        bitstring_init_ascii(pBitString, argv[argi]);
                        target_args++;
                    } else if (target_args == 10) {
                        pBitString = &event_data.notificationParams.changeOfBitstring.statusFlags;
                        bitstring_init_ascii(pBitString, argv[argi]);
                        target_args++;
                    } else if (target_args == 11) {
                        characterstring_init_ansi(&bcstring, argv[argi]);
                        event_data.messageText = &bcstring;
                        target_args++;
                    } else if (target_args == 12) {
                        event_data.notifyType = strtol(argv[argi], NULL, 0);
                        target_args++;
                    } else if (target_args == 13) {
                        event_data.ackRequired = strtol(argv[argi], NULL, 0);
                        target_args++;
                    } else if (target_args == 14) {
                        event_data.fromState = strtol(argv[argi], NULL, 0);
                        target_args++;
                    } else if (target_args == 15) {
                        event_data.toState = strtol(argv[argi], NULL, 0);
                        target_args++;
                    } else {
                        print_usage(filename);
                        return 1;
                    }
                } else if (event_data.eventType == EVENT_CHANGE_OF_STATE) {
                    if (target_args == 9) {
                        tag = strtol(argv[argi], NULL, 0);
                        event_data.notificationParams.changeOfState.newState.tag = tag;
                        target_args++;
                    } else if (target_args == 10) {
                        if (tag == BOOLEAN_VALUE) {
                            event_data.notificationParams.changeOfState.newState.state.booleanValue =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == BINARY_VALUE) {
                            event_data.notificationParams.changeOfState.newState.state.binaryValue =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == EVENT_TYPE) {
                            event_data.notificationParams.changeOfState.newState.state.eventType =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == POLARITY) {
                            event_data.notificationParams.changeOfState.newState.state.polarity =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == PROGRAM_CHANGE) {
                            event_data.notificationParams.changeOfState.newState.state.programChange =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == PROGRAM_STATE) {
                            event_data.notificationParams.changeOfState.newState.state.programState =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == REASON_FOR_HALT) {
                            event_data.notificationParams.changeOfState.newState.state.programError =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == RELIABILITY) {
                            event_data.notificationParams.changeOfState.newState.state.reliability =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == STATE) {
                            event_data.notificationParams.changeOfState.newState.state.state =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == SYSTEM_STATUS) {
                            event_data.notificationParams.changeOfState.newState.state.systemStatus =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == UNITS) {
                            event_data.notificationParams.changeOfState.newState.state.units =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == UNSIGNED_VALUE) {
                            event_data.notificationParams.changeOfState.newState.state.unsignedValue =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == LIFE_SAFETY_MODE) {
                            event_data.notificationParams.changeOfState.newState.state.lifeSafetyMode =
                                strtol(argv[argi], NULL, 0);
                        } else if (tag == LIFE_SAFETY_STATE) {
                            event_data.notificationParams.changeOfState.newState.state.lifeSafetyState =
                                strtol(argv[argi], NULL, 0);
                        } else {
                            printf("Invalid Change-Of-State Tag\n");
                            return 1;
                        }
                        target_args++;
                    } else if (target_args == 11) {
                        pBitString = &event_data.notificationParams.changeOfBitstring.statusFlags;
                        bitstring_init_ascii(pBitString, argv[argi]);
                        target_args++;
                    } else if (target_args == 12) {
                        characterstring_init_ansi(&bcstring, argv[argi]);
                        event_data.messageText = &bcstring;
                        target_args++;
                    } else if (target_args == 13) {
                        event_data.notifyType = strtol(argv[argi], NULL, 0);
                        target_args++;
                    } else if (target_args == 14) {
                        event_data.ackRequired = strtol(argv[argi], NULL, 0);
                        target_args++;
                    } else if (target_args == 15) {
                        event_data.fromState = strtol(argv[argi], NULL, 0);
                        target_args++;
                    } else if (target_args == 16) {
                        event_data.toState = strtol(argv[argi], NULL, 0);
                        target_args++;
                    } else {
                        print_usage(filename);
                        return 1;
                    }
                } else if (event_data.eventType == EVENT_CHANGE_OF_VALUE) {
                } else if (event_data.eventType == EVENT_COMMAND_FAILURE) {
                } else if (event_data.eventType == EVENT_FLOATING_LIMIT) {
                } else if (event_data.eventType == EVENT_OUT_OF_RANGE) {
                } else if (event_data.eventType == EVENT_CHANGE_OF_LIFE_SAFETY) {
                } else if (event_data.eventType == EVENT_EXTENDED) {
                } else if (event_data.eventType == EVENT_BUFFER_READY) {
                } else if (event_data.eventType == EVENT_UNSIGNED_RANGE) {
                } else {
                    print_usage(filename);
                    return 1;
                }
            }
        }
    }
    address_init();
    if (specific_address) {
        if (adr.len && mac.len) {
            memcpy(&dest.mac[0], &mac.adr[0], mac.len);
            dest.mac_len = mac.len;
            memcpy(&dest.adr[0], &adr.adr[0], adr.len);
            dest.len = adr.len;
            if ((dnet >= 0) && (dnet <= BACNET_BROADCAST_NETWORK)) {
                dest.net = dnet;
            } else {
                dest.net = BACNET_BROADCAST_NETWORK;
            }
        } else if (mac.len) {
            memcpy(&dest.mac[0], &mac.adr[0], mac.len);
            dest.mac_len = mac.len;
            dest.len = 0;
            if ((dnet >= 0) && (dnet <= BACNET_BROADCAST_NETWORK)) {
                dest.net = dnet;
            } else {
                dest.net = 0;
            }
        } else {
            if ((dnet >= 0) && (dnet <= BACNET_BROADCAST_NETWORK)) {
                dest.net = dnet;
            } else {
                dest.net = BACNET_BROADCAST_NETWORK;
            }
            dest.mac_len = 0;
            dest.len = 0;
        }
    }
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    Send_UEvent_Notify(&Handler_Transmit_Buffer[0], &event_data, &dest);

    return 0;
}
Exemple #25
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    time_t total_seconds = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    int argi = 0;
    char *filename = NULL;

    filename = filename_remove_path(argv[0]);
    for (argi = 1; argi < argc; argi++) {
        if (strcmp(argv[argi], "--help") == 0) {
            print_usage(filename);
            print_help(filename);
            exit(0);
        }
        if (strcmp(argv[argi], "--version") == 0) {
            printf("%s %s\n", filename, BACNET_VERSION_TEXT);
            printf("Copyright (C) 2014 by Steve Karg and others.\n"
                "This is free software; see the source for copying conditions.\n"
                "There is NO warranty; not even for MERCHANTABILITY or\n"
                "FITNESS FOR A PARTICULAR PURPOSE.\n");
            exit(0);
        }
    }
    if (argc < 2) {
        print_usage(filename);
        return 0;
    }
    if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
        return 0;
    }
    /* decode the command line parameters */
    address_parse(&Target_Router_Address, argc - 1, &argv[1]);
    if (argc > 2) {
        /* FIXME: add port info parse */
        /* BACNET_ROUTER_PORT *router_port_list
           Target_Router_Port_List
           ports_parse(&router_port[0], argc-2, &argv[2]);
           Target_Router_Port_List = router_port[0];
         */
    }
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    Init_Service_Handlers();
    address_init();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = apdu_timeout() / 1000;
    /* send the request */
    Send_Initialize_Routing_Table(&Target_Router_Address, DNET_list);
    /* loop forever */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);
        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
        /* process */
        if (pdu_len) {
            My_NPDU_Handler(&src, &Rx_Buf[0], pdu_len);
        }
        if (Error_Detected)
            break;
        /* increment timer - exit if timed out */
        elapsed_seconds = current_seconds - last_seconds;
        if (elapsed_seconds) {
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
        }
        total_seconds += elapsed_seconds;
        if (total_seconds > timeout_seconds)
            break;
        /* keep track of time for next check */
        last_seconds = current_seconds;
    }

    return 0;
}
Exemple #26
0
int main(
    int argc,
    char *argv[])
{
    char *value_string = NULL;
    bool status = false;
    BACNET_COV_DATA cov_data;
    BACNET_PROPERTY_VALUE value_list;
    uint8_t tag;

    if (argc < 7) {
        /* note: priority 16 and 0 should produce the same end results... */
        printf("Usage: %s pid device-id object-type object-instance "
            "time property tag value [priority] [index]\r\n" "\r\n" "pid:\r\n"
            "Process Identifier for this broadcast.\r\n" "\r\n"
            "device-id:\r\n"
            "The Initiating BACnet Device Object Instance number.\r\n" "\r\n"
            "object-type:\r\n"
            "The monitored object type is the integer value of the\r\n"
            "enumeration BACNET_OBJECT_TYPE in bacenum.h.  For example,\r\n"
            "if you were monitoring Analog Output 2, the object-type\r\n"
            "would be 1.\r\n" "\r\n" "object-instance:\r\n"
            "The monitored object instance number.\r\n" "\r\n" "time:\r\n"
            "The subscription time remaining is conveyed in seconds.\r\n"
            "\r\n" "property:\r\n"
            "The property is an integer value of the enumeration \r\n"
            "BACNET_PROPERTY_ID in bacenum.h. For example, if you were\r\n"
            "monitoring the Present Value property, you would use 85\r\n"
            "as the property.\r\n" "\r\n" "tag:\r\n"
            "Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \r\n"
            "in bacenum.h.  It is the data type of the value that you are\r\n"
            "monitoring.  For example, if you were monitoring a REAL value, you would \r\n"
            "use a tag of 4." "\r\n" "value:\r\n"
            "The value is an ASCII representation of some type of data that you\r\n"
            "are monitoring.  It is encoded using the tag information provided.  For\r\n"
            "example, if you were writing a REAL value of 100.0, you would use \r\n"
            "100.0 as the value.\r\n" "\r\n" "[priority]:\r\n"
            "This optional parameter is used for reporting the priority of the\r\n"
            "value. If no priority is given, none is sent, and the BACnet \r\n"
            "standard requires that the value is reported at the lowest \r\n"
            "priority (16) if the object property supports priorities.\r\n"
            "\r\n" "[index]\r\n"
            "This optional integer parameter is the index number of an array.\r\n"
            "If the property is an array, individual elements can be reported.\r\n"
            "\r\n" "Here is a brief overview of BACnet property and tags:\r\n"
            "Certain properties are expected to be written with certain \r\n"
            "application tags, so you probably need to know which ones to use\r\n"
            "with each property of each object.  It is almost safe to say that\r\n"
            "given a property and an object and a table, the tag could be looked\r\n"
            "up automatically.  There may be a few exceptions to this, such as\r\n"
            "the Any property type in the schedule object and the Present Value\r\n"
            "accepting REAL, BOOLEAN, NULL, etc.  Perhaps it would be simpler for\r\n"
            "the demo to use this kind of table - but I also wanted to be able\r\n"
            "to do negative testing by passing the wrong tag and have the server\r\n"
            "return a reject message.\r\n" "\r\n" "Example:\r\n"
            "If you want generate an unconfirmed COV,\r\n"
            "you could send the following command:\r\n"
            "%s 1 2 3 4 5 85 4 100.0\r\n"
            "where 1=pid, 2=device-id, 3=AV, 4=object-id, 5=time,\r\n"
            "85=Present-Value, 4=REAL, 100.0=value\r\n",
            filename_remove_path(argv[0]), filename_remove_path(argv[0]));
        return 0;
    }
    /* decode the command line parameters */
    cov_data.subscriberProcessIdentifier = strtol(argv[1], NULL, 0);
    cov_data.initiatingDeviceIdentifier = strtol(argv[2], NULL, 0);
    cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0);
    cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0);
    cov_data.timeRemaining = strtol(argv[5], NULL, 0);
    cov_data.listOfValues = &value_list;
    value_list.next = NULL;
    value_list.propertyIdentifier = strtol(argv[6], NULL, 0);
    tag = strtol(argv[7], NULL, 0);
    value_string = argv[8];
    /* optional priority */
    if (argc > 9)
        value_list.priority = strtol(argv[9], NULL, 0);
    else
        value_list.priority = BACNET_NO_PRIORITY;
    /* optional index */
    if (argc > 10)
        value_list.propertyArrayIndex = strtol(argv[10], NULL, 0);
    else
        value_list.propertyArrayIndex = BACNET_ARRAY_ALL;

    if (cov_data.initiatingDeviceIdentifier >= BACNET_MAX_INSTANCE) {
        fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
            cov_data.initiatingDeviceIdentifier, BACNET_MAX_INSTANCE);
        return 1;
    }
    if (cov_data.monitoredObjectIdentifier.type >= MAX_BACNET_OBJECT_TYPE) {
        fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
            cov_data.monitoredObjectIdentifier.type, MAX_BACNET_OBJECT_TYPE);
        return 1;
    }
    if (cov_data.monitoredObjectIdentifier.instance > BACNET_MAX_INSTANCE) {
        fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
            cov_data.monitoredObjectIdentifier.instance,
            BACNET_MAX_INSTANCE + 1);
        return 1;
    }
    if (cov_data.listOfValues->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
        fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
            cov_data.listOfValues->propertyIdentifier,
            MAX_BACNET_PROPERTY_ID + 1);
        return 1;
    }
    if (tag >= MAX_BACNET_APPLICATION_TAG) {
        fprintf(stderr, "tag=%u - it must be less than %u\r\n", tag,
            MAX_BACNET_APPLICATION_TAG);
        return 1;
    }
    status =
        bacapp_parse_application_data(tag, value_string,
        &cov_data.listOfValues->value);
    if (!status) {
        /* FIXME: show the expected entry format for the tag */
        fprintf(stderr, "unable to parse the tag value\r\n");
        return 1;
    }
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    Send_UCOV_Notify(&Handler_Transmit_Buffer[0], &cov_data);

    return 0;
}
Exemple #27
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    time_t total_seconds = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    long port = 0;

    if (argc < 2) {
        printf("Usage: %s IP [port]\r\n", filename_remove_path(argv[0]));
        return 0;
    }
    if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
        printf
            ("Send a Read-Broadcast-Distribution-Table message to a BBMD.\r\n"
            "\r\n" "IP:\r\n"
            "IP address of the BBMD in dotted decimal notation\r\n"
            "[port]\r\n"
            "optional BACnet/IP port number (default=47808=0xBAC0)\r\n" "\r\n"
            "To send a Read-Broadcast-Distribution-Table message to a BBMD\r\n"
            "at 192.168.0.1 using port 47808:\r\n" "%s 192.168.0.1 47808\r\n",
            filename_remove_path(argv[0]));
        return 0;
    }
    /* decode the command line parameters */
    if (argc > 1) {
        Target_BBMD_Address = inet_addr(argv[1]);
        if (Target_BBMD_Address == (-1)) {
            fprintf(stderr, "IP=%s - failed to convert address.\r\n", argv[1]);
            return 1;
        }
    }
    if (argc > 2) {
        port = strtol(argv[2], NULL, 0);
        if ((port > 0) && (port <= 65535)) {
            Target_BBMD_Port = htons(port);
        } else {
            fprintf(stderr, "port=%ld - port must be between 0-65535.\r\n",
                port);
            return 1;
        }
    } else {
        Target_BBMD_Port = htons(47808);
    }
    /* setup my info */
    Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
    Init_Service_Handlers();
    address_init();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    timeout_seconds = apdu_timeout() / 1000;
    /* send the request */
    bvlc_bbmd_read_bdt(Target_BBMD_Address, Target_BBMD_Port);
    /* loop forever */
    for (;;) {
        /* increment timer - exit if timed out */
        current_seconds = time(NULL);
        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        if (Error_Detected)
            break;
        /* increment timer - exit if timed out */
        elapsed_seconds = current_seconds - last_seconds;
        if (elapsed_seconds) {
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
        }
        total_seconds += elapsed_seconds;
        if (total_seconds > timeout_seconds)
            break;
        /* keep track of time for next check */
        last_seconds = current_seconds;
    }

    return 0;
}
Exemple #28
0
/** Main function of server demo.
 *
 * @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am,
 *      datalink_receive, npdu_handler,
 *      dcc_timer_seconds, bvlc_maintenance_timer,
 *      Load_Control_State_Machine_Handler, handler_cov_task,
 *      tsm_timer_milliseconds
 *
 * @param argc [in] Arg count.
 * @param argv [in] Takes one argument: the Device Instance #.
 * @return 0 on success.
 */
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 1;       /* milliseconds */
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    uint32_t elapsed_seconds = 0;
    uint32_t elapsed_milliseconds = 0;
    uint32_t address_binding_tmr = 0;
#if defined(INTRINSIC_REPORTING)
    uint32_t recipient_scan_tmr = 0;
#endif
#if defined(BACNET_TIME_MASTER)
    BACNET_DATE_TIME bdatetime;
#endif
#if defined(BAC_UCI)
    int uciId = 0;
    const char *uciName;
    struct uci_context *ctx;
#if defined(AI)
    time_t ucimodtime_bacnet_ai = 0;
#endif
#if defined(AO)
    time_t ucimodtime_bacnet_ao = 0;
#endif
#if defined(AV)
    time_t ucimodtime_bacnet_av = 0;
#endif
#if defined(BI)
    time_t ucimodtime_bacnet_bi = 0;
#endif
#if defined(BO)
    time_t ucimodtime_bacnet_bo = 0;
#endif
#if defined(BV)
    time_t ucimodtime_bacnet_bv = 0;
#endif
#if defined(MSI)
    time_t ucimodtime_bacnet_mi = 0;
#endif
#if defined(MSO)
    time_t ucimodtime_bacnet_mo = 0;
#endif
#if defined(MSV)
    time_t ucimodtime_bacnet_mv = 0;
#endif
    int rewrite = 0;
#endif
    int argi = 0;
    const char *filename = NULL;

    filename = filename_remove_path(argv[0]);
    for (argi = 1; argi < argc; argi++) {
        if (strcmp(argv[argi], "--help") == 0) {
            print_usage(filename);
            print_help(filename);
            return 0;
        }
        if (strcmp(argv[argi], "--version") == 0) {
            printf("%s %s\n", filename, BACNET_VERSION_TEXT);
            printf("Copyright (C) 2014 by Steve Karg and others.\n"
                "This is free software; see the source for copying conditions.\n"
                "There is NO warranty; not even for MERCHANTABILITY or\n"
                "FITNESS FOR A PARTICULAR PURPOSE.\n");
            return 0;
        }
    }
#if defined(BAC_UCI)
    char *pEnv = getenv("UCI_SECTION");
    if (!pEnv) {
       	pEnv = "0";
#if PRINT_ENABLED
        fprintf(stderr,  "Failed to getenv(UCI_SECTION)\n");
    } else {
	    fprintf(stderr,  "load config file bacnet_dev %s\n",pEnv);
#endif
    }

    ctx = ucix_init("bacnet_dev");
#if PRINT_ENABLED
    if(!ctx)
        fprintf(stderr,  "Failed to load config file bacnet_dev\n");
#endif

    uciId = ucix_get_option_int(ctx, "bacnet_dev", pEnv, "Id", 0);
    uciName = ucix_get_option(ctx, "bacnet_dev", pEnv, "name");
    if(ctx) 
        ucix_cleanup(ctx);
    if (uciId != 0) {
        Device_Set_Object_Instance_Number(uciId);
        if (uciName)
#if PRINT_ENABLED
            fprintf(stderr, "BACnet Device Name: %s\n", uciName);
#endif
            Device_Object_Name_ANSI_Init(uciName);
    } else {
#endif /* defined(BAC_UCI) */
        /* allow the device ID to be set */
        if (argc > 1) {
            Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
        }
        if (argc > 2) {
            Device_Object_Name_ANSI_Init(argv[2]);
        }
#if defined(BAC_UCI)
    }

#if defined(AI)
    char ai_path[128];
    struct stat ai_s;
	snprintf(ai_path, sizeof(ai_path), "/etc/config/bacnet_ai");
	if( stat(ai_path, &ai_s) > -1 )
		ucimodtime_bacnet_ai = ai_s.st_mtime;
#endif
#if defined(AO)
    char ao_path[128];
    struct stat ao_s;
	snprintf(ao_path, sizeof(ao_path), "/etc/config/bacnet_ao");
	if( stat(ao_path, &ao_s) > -1 )
		ucimodtime_bacnet_ao = ao_s.st_mtime;
#endif
#if defined(AV)
    char av_path[128];
    struct stat av_s;
	snprintf(av_path, sizeof(av_path), "/etc/config/bacnet_av");
	if( stat(av_path, &av_s) > -1 )
		ucimodtime_bacnet_av = av_s.st_mtime;
#endif
#if defined(BI)
    char bi_path[128];
    struct stat bi_s;
	snprintf(bi_path, sizeof(bi_path), "/etc/config/bacnet_bi");
	if( stat(bi_path, &bi_s) > -1 )
		ucimodtime_bacnet_bi = bi_s.st_mtime;
#endif
#if defined(BO)
    char bo_path[128];
    struct stat bo_s;
	snprintf(bo_path, sizeof(bo_path), "/etc/config/bacnet_bo");
	if( stat(bo_path, &bo_s) > -1 )
		ucimodtime_bacnet_bo = bo_s.st_mtime;
#endif
#if defined(BV)
    char bv_path[128];
    struct stat bv_s;
	snprintf(bv_path, sizeof(bv_path), "/etc/config/bacnet_bv");
	if( stat(bv_path, &bv_s) > -1 )
		ucimodtime_bacnet_bv = bv_s.st_mtime;
#endif
#if defined(MSI)
    char msi_path[128];
    struct stat msi_s;
	snprintf(msi_path, sizeof(msi_path), "/etc/config/bacnet_mi");
	if( stat(msi_path, &msi_s) > -1 )
		ucimodtime_bacnet_mi = msi_s.st_mtime;
#endif
#if defined(MSO)
    char mso_path[128];
    struct stat mso_s;
	snprintf(mso_path, sizeof(mso_path), "/etc/config/bacnet_mo");
	if( stat(mso_path, &mso_s) > -1 )
		ucimodtime_bacnet_mo = mso_s.st_mtime;
#endif
#if defined(MSV)
    char msv_path[128];
    struct stat msv_s;
	snprintf(msv_path, sizeof(msv_path), "/etc/config/bacnet_mv");
	if( stat(msv_path, &msv_s) > -1 )
		ucimodtime_bacnet_mv = msv_s.st_mtime;
#endif
#endif /* defined(BAC_UCI) */

#if PRINT_ENABLED
    printf("BACnet Server Demo\n" "BACnet Stack Version %s\n"
        "BACnet Device ID: %u\n" "Max APDU: %d\n", BACnet_Version,
        Device_Object_Instance_Number(), MAX_APDU);
#endif
    /* load any static address bindings to show up
       in our device bindings list */
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    /* broadcast an I-Am on startup */
    Send_I_Am(&Handler_Transmit_Buffer[0]);
    /* loop forever */
    for (;;) {
        /* input */
        current_seconds = time(NULL);

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* at least one second has passed */
        elapsed_seconds = (uint32_t) (current_seconds - last_seconds);
        if (elapsed_seconds) {
            last_seconds = current_seconds;
            dcc_timer_seconds(elapsed_seconds);
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
            dlenv_maintenance_timer(elapsed_seconds);
#if defined(LC)
            Load_Control_State_Machine_Handler();
#endif
            elapsed_milliseconds = elapsed_seconds * 1000;
            handler_cov_timer_seconds(elapsed_seconds);
            tsm_timer_milliseconds(elapsed_milliseconds);
#if defined(TRENDLOG)
            trend_log_timer(elapsed_seconds);
#endif
#if defined(INTRINSIC_REPORTING)
            Device_local_reporting();
#endif
#if defined(BACNET_TIME_MASTER)
            Device_getCurrentDateTime(&bdatetime);
            handler_timesync_task(&bdatetime);
#endif
        }
        handler_cov_task();
        /* scan cache address */
        address_binding_tmr += elapsed_seconds;
        if (address_binding_tmr >= 60) {
            address_cache_timer(address_binding_tmr);
            address_binding_tmr = 0;
        }
#if defined(INTRINSIC_REPORTING)
        /* try to find addresses of recipients */
        recipient_scan_tmr += elapsed_seconds;
        if (recipient_scan_tmr >= NC_RESCAN_RECIPIENTS_SECS) {
            Notification_Class_find_recipient();
            recipient_scan_tmr = 0;
        }
#endif
        /* output */
#if defined(BAC_UCI)
        rewrite++;
        if (rewrite>100000) {
#if PRINT_ENABLED
            printf("rewrite interval %i\n", rewrite);
#endif
            rewrite=0;
        }
#if defined(AI)
        /* update Analog Input from uci */
        ucimodtime_bacnet_ai = uci_Update(ucimodtime_bacnet_ai,OBJECT_ANALOG_INPUT,rewrite);
#endif
#if defined(AO)
        /* update Analog Output from uci */
        ucimodtime_bacnet_ao = uci_Update(ucimodtime_bacnet_ao,OBJECT_ANALOG_OUTPUT,rewrite);
#endif
#if defined(AV)
        /* update Analog Value from uci */
        ucimodtime_bacnet_av = uci_Update(ucimodtime_bacnet_av,OBJECT_ANALOG_VALUE,rewrite);
#endif
#if defined(BI)
        /* update Binary Input from uci */
        ucimodtime_bacnet_bi = uci_Update(ucimodtime_bacnet_bi,OBJECT_BINARY_INPUT,rewrite);
#endif
#if defined(BO)
        /* update Binary Output from uci */
        ucimodtime_bacnet_bo = uci_Update(ucimodtime_bacnet_bo,OBJECT_BINARY_OUTPUT,rewrite);
#endif
#if defined(BV)
        /* update Binary Value from uci */
        ucimodtime_bacnet_bv = uci_Update(ucimodtime_bacnet_bv,OBJECT_BINARY_VALUE,rewrite);
#endif
#if defined(MSI)
        /* update Multistate Input from uci */
        ucimodtime_bacnet_mi = uci_Update(ucimodtime_bacnet_mi,OBJECT_MULTI_STATE_INPUT,rewrite);
#endif
#if defined(MSO)
        /* update Multistate Output from uci */
        ucimodtime_bacnet_mo = uci_Update(ucimodtime_bacnet_mo,OBJECT_MULTI_STATE_OUTPUT,rewrite);
#endif
#if defined(MSV)
        /* update Multistate Value from uci */
        ucimodtime_bacnet_mv = uci_Update(ucimodtime_bacnet_mv,OBJECT_MULTI_STATE_VALUE,rewrite);
#endif
#endif /* defined(BAC_UCI) */

        /* blink LEDs, Turn on or off outputs, etc */
    }

    return 0;
}
Exemple #29
0
/** Main function of server demo.
 *
 * @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am,
 *      datalink_receive, npdu_handler,
 *      dcc_timer_seconds, bvlc_maintenance_timer,
 *      Load_Control_State_Machine_Handler, handler_cov_task,
 *      tsm_timer_milliseconds
 *
 * @param argc [in] Arg count.
 * @param argv [in] Takes one argument: the Device Instance #.
 * @return 0 on success.
 */
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 1;       /* milliseconds */
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    uint32_t elapsed_seconds = 0;
    uint32_t elapsed_milliseconds = 0;
    uint32_t address_binding_tmr = 0;
    uint32_t recipient_scan_tmr = 0;
    int uci_id = 0;
    float val_f, pval_f;
    int val_i, pval_i;
    struct uci_context *ctx;
    time_t chk_mtime = 0;
    time_t ucimodtime_bacnet_bi = 0;
    time_t ucimodtime_bacnet_av = 0;
    time_t ucimodtime_bacnet_ao = 0;
    time_t ucimodtime_bacnet_mv = 0;
    int uci_idx = 0;
    char *section;
    char *type;
    char *pEnv = NULL;
    int rewrite;

    pEnv = getenv("UCI_SECTION");
    ctx = ucix_init("bacnet_dev");
#if PRINT_ENABLED
    if(!ctx)
        fprintf(stderr,  "Failed to load config file bacnet_dev\n");
#endif
    uci_id = ucix_get_option_int(ctx, "bacnet_dev", pEnv, "id", 0);
    if (uci_id != 0) {
        Device_Set_Object_Instance_Number(uci_id);
    } else {
        /* allow the device ID to be set */
        if (argc > 1)
            Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
    }
    if(ctx)
        ucix_cleanup(ctx);

#if PRINT_ENABLED
    printf("BACnet Server with uci\n" "BACnet Stack Version %s\n"
        "BACnet Device ID: %u\n" "Max APDU: %d\n", BACnet_Version,
        Device_Object_Instance_Number(), MAX_APDU);
#endif
    /* load any static address bindings to show up
       in our device bindings list */
    address_init();
    Init_Service_Handlers();
    dlenv_init();
    atexit(datalink_cleanup);
    /* configure the timeout values */
    last_seconds = time(NULL);
    /* broadcast an I-Am on startup */
    Send_I_Am(&Handler_Transmit_Buffer[0]);
    /* loop forever */
    for (;;) {
        /* input */
        current_seconds = time(NULL);

        /* returns 0 bytes on timeout */
        pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);

        /* process */
        if (pdu_len) {
            npdu_handler(&src, &Rx_Buf[0], pdu_len);
        }
        /* at least one second has passed */
        elapsed_seconds = (uint32_t) (current_seconds - last_seconds);
        if (elapsed_seconds) {
            last_seconds = current_seconds;
            dcc_timer_seconds(elapsed_seconds);
#if defined(BACDL_BIP) && BBMD_ENABLED
            bvlc_maintenance_timer(elapsed_seconds);
#endif
            dlenv_maintenance_timer(elapsed_seconds);
            Load_Control_State_Machine_Handler();
            elapsed_milliseconds = elapsed_seconds * 1000;
            handler_cov_timer_seconds(elapsed_seconds);
            tsm_timer_milliseconds(elapsed_milliseconds);
            trend_log_timer(elapsed_seconds);
#if defined(INTRINSIC_REPORTING)
            Device_local_reporting();
#endif
        }
        handler_cov_task();
        /* scan cache address */
        address_binding_tmr += elapsed_seconds;
        if (address_binding_tmr >= 60) {
            address_cache_timer(address_binding_tmr);
            address_binding_tmr = 0;
        }
#if defined(INTRINSIC_REPORTING)
        /* try to find addresses of recipients */
        recipient_scan_tmr += elapsed_seconds;
        if (recipient_scan_tmr >= NC_RESCAN_RECIPIENTS_SECS) {
            Notification_Class_find_recipient();
            recipient_scan_tmr = 0;
        }
#endif
#if false
        /* output */
        rewrite++;
        if (rewrite>10000) {
            rewrite=0;
            printf("rewrite %i\n", rewrite);
        }
        /* update Analog Value from uci */
        section = "bacnet_av";
        type = "av";
        chk_mtime = 0;
        chk_mtime = check_uci_update(section, ucimodtime_bacnet_av);
        if ( rewrite == 0) {
            chk_mtime = ucimodtime_bacnet_av;
#if PRINT_ENABLED
            printf("rewrite %i\n", rewrite);
#endif
        }
        if(chk_mtime != 0) {
            sleep(1);
            ucimodtime_bacnet_av = chk_mtime;
#if PRINT_ENABLED
            printf("Config changed, reloading %s\n",section);
#endif
            ctx = ucix_init(section);
            struct uci_itr_ctx itr;
            value_tuple_t *cur;
            itr.list = NULL;
            itr.section = section;
            itr.ctx = ctx;
            ucix_for_each_section_type(ctx, section, type,
                (void *)load_value, &itr);
            for( cur = itr.list; cur; cur = cur->next ) {
#if PRINT_ENABLED
                printf("section %s idx %s \n", section, cur->idx);
#endif
                val_f = strtof(cur->value,NULL);
                uci_idx = atoi(cur->idx);
#if PRINT_ENABLED
                printf("idx %s ",cur->idx);
                printf("value %s\n",cur->value);
#endif
                pval_f = Analog_Value_Present_Value(uci_idx);
                if ( val_f != pval_f ) {
                    Analog_Value_Present_Value_Set(uci_idx,val_f,16);
                }
                if (cur->Out_Of_Service == 0) {
                    if (Analog_Value_Out_Of_Service(uci_idx))
                        Analog_Value_Out_Of_Service_Set(uci_idx,0);
                    if (Analog_Value_Reliability(uci_idx))
                        Analog_Value_Reliability_Set(uci_idx,
                            RELIABILITY_NO_FAULT_DETECTED);
                } else {
#if PRINT_ENABLED
                    printf("idx %s ",cur->idx);
                    printf("Out_Of_Service\n");
#endif
                    Analog_Value_Out_Of_Service_Set(uci_idx,1);
                    Analog_Value_Reliability_Set(uci_idx,
                        RELIABILITY_COMMUNICATION_FAILURE);
                }
            }
            ucix_cleanup(ctx);
        }
        /* update end */
        /* update Analog Value from uci */
        section = "bacnet_ao";
        type = "ao";
        chk_mtime = 0;
        chk_mtime = check_uci_update(section, ucimodtime_bacnet_ao);
        if ( rewrite == 0) {
            chk_mtime = ucimodtime_bacnet_ao;
        }
        if(chk_mtime != 0) {
            sleep(1);
            ucimodtime_bacnet_ao = chk_mtime;
#if PRINT_ENABLED
            printf("Config changed, reloading %s\n",section);
#endif
            ctx = ucix_init(section);
            struct uci_itr_ctx itr;
            value_tuple_t *cur;
            itr.list = NULL;
            itr.section = section;
            itr.ctx = ctx;
            ucix_for_each_section_type(ctx, section, type,
                (void *)load_value, &itr);
            for( cur = itr.list; cur; cur = cur->next ) {
#if PRINT_ENABLED
                printf("section %s idx %s \n", section, cur->idx);
#endif
                val_f = strtof(cur->value,NULL);
                uci_idx = atoi(cur->idx);
#if PRINT_ENABLED
                printf("idx %s ",cur->idx);
                printf("value %s\n",cur->value);
#endif
                pval_f = Analog_Output_Present_Value(uci_idx);
                if ( val_f != pval_f ) {
                    Analog_Output_Present_Value_Set(uci_idx,val_f,16);
                }
                if (cur->Out_Of_Service == 0) {
                    if (Analog_Output_Out_Of_Service(uci_idx))
                        Analog_Output_Out_Of_Service_Set(uci_idx,0);
                    if (Analog_Output_Reliability(uci_idx))
                        Analog_Output_Reliability_Set(uci_idx,
                            RELIABILITY_NO_FAULT_DETECTED);
                } else {
#if PRINT_ENABLED
                    printf("idx %s ",cur->idx);
                    printf("Out_Of_Service\n");
#endif
                    Analog_Output_Out_Of_Service_Set(uci_idx,1);
                    Analog_Output_Reliability_Set(uci_idx,
                        RELIABILITY_COMMUNICATION_FAILURE);
                }
            }
            ucix_cleanup(ctx);
        }
        /* update end */

        /* update Multistate Value from uci */
        section = "bacnet_mv";
        type = "mv";
        chk_mtime = 0;
        chk_mtime = check_uci_update(section, ucimodtime_bacnet_mv);
        if ( rewrite == 0) {
            chk_mtime = ucimodtime_bacnet_mv;
        }
        if(chk_mtime != 1) {
            ucimodtime_bacnet_mv = chk_mtime;
#if PRINT_ENABLED
            printf("Config changed, reloading %s\n",section);
#endif
            ctx = ucix_init(section);
            struct uci_itr_ctx itr;
            value_tuple_t *cur;
            itr.list = NULL;
            itr.section = section;
            itr.ctx = ctx;
            ucix_for_each_section_type(ctx, section, type,
                (void *)load_value, &itr);
            for( cur = itr.list; cur; cur = cur->next ) {
#if PRINT_ENABLED
                printf("section %s idx %s \n", section, cur->idx);
#endif
                val_f = strtof(cur->value,NULL);
                uci_idx = atoi(cur->idx);
                if (val_f || !strcmp(cur->value, "0")) {
#if PRINT_ENABLED
                    printf("idx %s ",cur->idx);
                    printf("value %s\n",cur->value);
#endif
                    pval_f = Multistate_Value_Present_Value(uci_idx);
                    if ( val_f != pval_f ) {
                        Multistate_Value_Present_Value_Set(uci_idx,val_f,16);
                    }
                    if (Multistate_Value_Out_Of_Service(uci_idx))
                        Multistate_Value_Out_Of_Service_Set(uci_idx,0);
                    if (Multistate_Value_Reliability(uci_idx))
                        Multistate_Value_Reliability_Set(uci_idx,
                            RELIABILITY_NO_FAULT_DETECTED);
                } else {
#if PRINT_ENABLED
                    printf("idx %s ",cur->idx);
                    printf("Out_Of_Service\n");
#endif
                    Multistate_Value_Out_Of_Service_Set(uci_idx,1);
                    Multistate_Value_Reliability_Set(uci_idx,
                        RELIABILITY_COMMUNICATION_FAILURE);
                }
                if (cur->Out_Of_Service == 0) {
                    if (Multistate_Value_Out_Of_Service(uci_idx))
                        Multistate_Value_Out_Of_Service_Set(uci_idx,0);
                    if (Multistate_Value_Reliability(uci_idx))
                        Multistate_Value_Reliability_Set(uci_idx,
                            RELIABILITY_NO_FAULT_DETECTED);
                } else {
#if PRINT_ENABLED
                    printf("idx %s ",cur->idx);
                    printf("Out_Of_Service\n");
#endif
                    Multistate_Value_Out_Of_Service_Set(uci_idx,1);
                    Multistate_Value_Reliability_Set(uci_idx,
                        RELIABILITY_COMMUNICATION_FAILURE);
                }
            }
            ucix_cleanup(ctx);
        }
        /* update end */

        /* update Binary Input from uci */
        section = "bacnet_bi";
        type = "bi";
        chk_mtime = 0;
        chk_mtime = check_uci_update(section, ucimodtime_bacnet_bi);
        if ( rewrite == 0) {
            chk_mtime = ucimodtime_bacnet_bi;
        }
        if(chk_mtime != 0) {
            ucimodtime_bacnet_bi = chk_mtime;
#if PRINT_ENABLED
            printf("Config changed, reloading %s\n",section);
#endif
            ctx = ucix_init(section);
            struct uci_itr_ctx itr;
            value_tuple_t *cur;
            itr.list = NULL;
            itr.section = section;
            itr.ctx = ctx;
            ucix_for_each_section_type(ctx, section, type,
                (void *)load_value, &itr);
            for( cur = itr.list; cur; cur = cur->next ) {
#if PRINT_ENABLED
                printf("section %s idx %s \n", section, cur->idx);
#endif
                if (cur->value) {
#if PRINT_ENABLED
                    printf("idx %s ",cur->idx);
                    printf("value %s\n",cur->value);
#endif
                    val_i = atoi(cur->value);
                    uci_idx = atoi(cur->idx);
                    pval_i = Binary_Input_Present_Value(uci_idx);
                    if ( val_i != pval_i ) {
                        Binary_Input_Present_Value_Set(uci_idx,val_i,16);
                    }
                }
                if (cur->Out_Of_Service == 0) {
                    if (Binary_Input_Out_Of_Service(uci_idx))
                        Binary_Input_Out_Of_Service_Set(uci_idx,0);
                    if (Binary_Input_Reliability(uci_idx))
                        Binary_Input_Reliability_Set(uci_idx,
                            RELIABILITY_NO_FAULT_DETECTED);
                } else {
#if PRINT_ENABLED
                    printf("idx %s ",cur->idx);
                    printf("Out_Of_Service\n");
#endif
                    Binary_Input_Out_Of_Service_Set(uci_idx,1);
                    Binary_Input_Reliability_Set(uci_idx,
                        RELIABILITY_COMMUNICATION_FAILURE);
                }
            }
            ucix_cleanup(ctx);
        }
        /* update end */
#endif
        /* blink LEDs, Turn on or off outputs, etc */
    }

    return 0;
}
Exemple #30
0
/* returns true if successful */
bool Device_Write_Property(
    BACNET_WRITE_PROPERTY_DATA * wp_data,
    BACNET_ERROR_CLASS * error_class,
    BACNET_ERROR_CODE * error_code)
{
    bool status = false;        /* return value */
    int len = 0;
    BACNET_APPLICATION_DATA_VALUE value;

    if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) {
        *error_class = ERROR_CLASS_OBJECT;
        *error_code = ERROR_CODE_UNKNOWN_OBJECT;
        return false;
    }
    /* decode the some of the request */
    len =
        bacapp_decode_application_data(wp_data->application_data,
        wp_data->application_data_len, &value);
    /* FIXME: len < application_data_len: more data? */
    /* FIXME: len == 0: unable to decode? */
    switch (wp_data->object_property) {
        case PROP_OBJECT_IDENTIFIER:
            if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
                if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
                    (Device_Set_Object_Instance_Number(value.type.
                            Object_Id.instance))) {
                    /* FIXME: we could send an I-Am broadcast to let the world know */
                    status = true;
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_NUMBER_OF_APDU_RETRIES:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                /* FIXME: bounds check? */
                apdu_retries_set((uint8_t) value.type.Unsigned_Int);
                status = true;
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_APDU_TIMEOUT:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                /* FIXME: bounds check? */
                apdu_timeout_set((uint16_t) value.type.Unsigned_Int);
                status = true;
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_VENDOR_IDENTIFIER:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                /* FIXME: bounds check? */
                Device_Set_Vendor_Identifier((uint16_t) value.
                    type.Unsigned_Int);
                status = true;
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_SYSTEM_STATUS:
            if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
                /* FIXME: bounds check? */
                Device_Set_System_Status((BACNET_DEVICE_STATUS) value.
                    type.Enumerated);
                status = true;
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_OBJECT_NAME:
            if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
                uint8_t encoding;
                encoding =
                    characterstring_encoding(&value.type.Character_String);
                if (encoding == CHARACTER_ANSI_X34) {
                    status =
                        Device_Set_Object_Name(characterstring_value
                        (&value.type.Character_String),
                        characterstring_length(&value.type.Character_String));
                    if (!status) {
                        *error_class = ERROR_CLASS_PROPERTY;
                        *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
                    }
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
#if defined(BACDL_MSTP)
        case PROP_MAX_INFO_FRAMES:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if (value.type.Unsigned_Int <= 255) {
                    dlmstp_set_max_info_frames((uint8_t) value.
                        type.Unsigned_Int);
                    status = true;
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
        case PROP_MAX_MASTER:
            if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
                if ((value.type.Unsigned_Int > 0) &&
                    (value.type.Unsigned_Int <= 127)) {
                    dlmstp_set_max_master((uint8_t) value.type.Unsigned_Int);
                    status = true;
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                *error_class = ERROR_CLASS_PROPERTY;
                *error_code = ERROR_CODE_INVALID_DATA_TYPE;
            }
            break;
#endif
        default:
            *error_class = ERROR_CLASS_PROPERTY;
            *error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
            break;
    }

    return status;
}