Esempio n. 1
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;
}
Esempio n. 2
0
/* returns true if successful */
bool Analog_Value_Write_Property(
    BACNET_WRITE_PROPERTY_DATA * wp_data)
{
    bool status = false;        /* return value */
    unsigned int object_index = 0;
    int len = 0;
    BACNET_APPLICATION_DATA_VALUE value;
    ANALOG_VALUE_DESCR *CurrentAV;

    /* 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_PRIORITY_ARRAY) &&
        (wp_data->object_property != PROP_EVENT_TIME_STAMPS) &&
        (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;
    }
    object_index = Analog_Value_Instance_To_Index(wp_data->object_instance);
    if (object_index < MAX_ANALOG_VALUES)
        CurrentAV = &AV_Descr[object_index];
    else
        return false;

    switch (wp_data->object_property) {
        case PROP_PRESENT_VALUE:
            if (value.tag == BACNET_APPLICATION_TAG_REAL) {
                /* Command priority 6 is reserved for use by Minimum On/Off
                   algorithm and may not be used for other purposes in any
                   object. */
                if (Analog_Value_Present_Value_Set(wp_data->object_instance,
                        value.type.Real, wp_data->priority)) {
                    status = true;
                } else if (wp_data->priority == 6) {
                    /* Command priority 6 is reserved for use by Minimum On/Off
                       algorithm and may not be used for other purposes in any
                       object. */
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else {
                status = false;
                wp_data->error_class = ERROR_CLASS_PROPERTY;
                wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
            }
            break;

        case PROP_OUT_OF_SERVICE:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
                &wp_data->error_class, &wp_data->error_code);
            if (status) {
                CurrentAV->Out_Of_Service = value.type.Boolean;
            }
            break;

        case PROP_UNITS:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,
                &wp_data->error_class, &wp_data->error_code);
            if (status) {
                CurrentAV->Units = value.type.Enumerated;
            }
            break;

#if defined(INTRINSIC_REPORTING)
        case PROP_TIME_DELAY:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                CurrentAV->Time_Delay = value.type.Unsigned_Int;
                CurrentAV->Remaining_Time_Delay = CurrentAV->Time_Delay;
            }
            break;

        case PROP_NOTIFICATION_CLASS:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                CurrentAV->Notification_Class = value.type.Unsigned_Int;
            }
            break;

        case PROP_HIGH_LIMIT:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                CurrentAV->High_Limit = value.type.Real;
            }
            break;

        case PROP_LOW_LIMIT:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                CurrentAV->Low_Limit = value.type.Real;
            }
            break;

        case PROP_DEADBAND:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                CurrentAV->Deadband = value.type.Real;
            }
            break;

        case PROP_LIMIT_ENABLE:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_BIT_STRING,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                if (value.type.Bit_String.bits_used == 2) {
                    CurrentAV->Limit_Enable = value.type.Bit_String.value[0];
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                    status = false;
                }
            }
            break;

        case PROP_EVENT_ENABLE:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_BIT_STRING,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                if (value.type.Bit_String.bits_used == 3) {
                    CurrentAV->Event_Enable = value.type.Bit_String.value[0];
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                    status = false;
                }
            }
            break;

        case PROP_NOTIFY_TYPE:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                switch ((BACNET_NOTIFY_TYPE) value.type.Enumerated) {
                    case NOTIFY_EVENT:
                        CurrentAV->Notify_Type = 1;
                        break;
                    case NOTIFY_ALARM:
                        CurrentAV->Notify_Type = 0;
                        break;
                    default:
                        wp_data->error_class = ERROR_CLASS_PROPERTY;
                        wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                        status = false;
                        break;
                }
            }
            break;
#endif
        case PROP_OBJECT_IDENTIFIER:
        case PROP_OBJECT_NAME:
        case PROP_OBJECT_TYPE:
        case PROP_STATUS_FLAGS:
        case PROP_EVENT_STATE:
        case PROP_DESCRIPTION:
#if defined(INTRINSIC_REPORTING)
        case PROP_ACKED_TRANSITIONS:
        case PROP_EVENT_TIME_STAMPS:
#endif
            wp_data->error_class = ERROR_CLASS_PROPERTY;
            wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
            break;
        case PROP_RELINQUISH_DEFAULT:
        case PROP_PRIORITY_ARRAY:
        default:
            wp_data->error_class = ERROR_CLASS_PROPERTY;
            wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
            break;
    }

    return status;
}
Esempio n. 3
0
/* returns true if successful */
bool Analog_Value_Write_Property(
    BACNET_WRITE_PROPERTY_DATA * wp_data)
{
    bool status = false;        /* return value */
#if 0
    unsigned int object_index = 0;
    unsigned int priority = 0;
#endif
    BACNET_APPLICATION_DATA_VALUE value;
    int len = 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_PRIORITY_ARRAY) &&
        (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 (wp_data->object_property) {
        case PROP_PRESENT_VALUE:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
                &wp_data->error_class, &wp_data->error_code);
            if (status) {
                status =
                    Analog_Value_Present_Value_Set(wp_data->object_instance,
                    value.type.Real, wp_data->priority);
                if (!status) {
                    if (wp_data->priority == 6) {
                        /* Command priority 6 is reserved for use by Minimum On/Off
                           algorithm and may not be used for other purposes in any
                           object. */
                        wp_data->error_class = ERROR_CLASS_PROPERTY;
                        wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
                    } else {
                        wp_data->error_class = ERROR_CLASS_PROPERTY;
                        wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                    }
                }
            }
            break;
        case PROP_OUT_OF_SERVICE:
#if 0
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
                &wp_data->error_class, &wp_data->error_code);
            if (status) {
                object_index =
                    Analog_Value_Instance_To_Index(wp_data->object_instance);
                Analog_Value_Out_Of_Service[object_index] = value.type.Boolean;
            }
            break;
#endif
        case PROP_UNITS:
#if 0
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
                &wp_data->error_class, &wp_data->error_code);
            if (status) {
                object_index =
                    Analog_Value_Instance_To_Index(wp_data->object_instance);
                Analog_Value_Units[object_index] = value.type.Unsigned_Int;
            }
            break;
#endif
        case PROP_PRIORITY_ARRAY:
        case PROP_OBJECT_IDENTIFIER:
        case PROP_OBJECT_NAME:
        case PROP_OBJECT_TYPE:
        case PROP_STATUS_FLAGS:
        case PROP_EVENT_STATE:
        case PROP_DESCRIPTION:
            wp_data->error_class = ERROR_CLASS_PROPERTY;
            wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
            break;
        case PROP_RELINQUISH_DEFAULT:
        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;
}
Esempio n. 4
0
static time_t uci_Update(
	time_t ucimodtime,
	BACNET_OBJECT_TYPE update_object_type,
	int ucirewrite
	)
{
	char *section;
	char *type;
	time_t chk_mtime = 0;
	struct uci_context *ctx;
	int uci_idx;
	/* update Value from uci */
	section = NULL;
	type = NULL;
	if (false) {
		section = NULL;
		type = NULL;
#if defined(AI)
	} else if (update_object_type == OBJECT_ANALOG_INPUT) {
		section = "bacnet_ai";
		type = "ai";
#endif
#if defined(AO)
	} else if (update_object_type == OBJECT_ANALOG_OUTPUT) {
		section = "bacnet_ao";
		type = "ao";
#endif
#if defined(AV)
	} else if (update_object_type == OBJECT_ANALOG_VALUE) {
		section = "bacnet_av";
		type = "av";
#endif
#if defined(BI)
	} else if (update_object_type == OBJECT_BINARY_INPUT) {
		section = "bacnet_bi";
		type = "bi";
#endif
#if defined(BO)
	} else if (update_object_type == OBJECT_BINARY_OUTPUT) {
		section = "bacnet_bo";
		type = "bo";
#endif
#if defined(BV)
	} else if (update_object_type == OBJECT_BINARY_VALUE) {
		section = "bacnet_bv";
		type = "bv";
#endif
#if defined(MI)
	} else if (update_object_type == OBJECT_MULTI_STATE_INPUT) {
		section = "bacnet_mi";
		type = "mi";
#endif
#if defined(MO)
	} else if (update_object_type == OBJECT_MULTI_STATE_OUTPUT) {
		section = "bacnet_mo";
		type = "mo";
#endif
#if defined(MSV)
	} else if (update_object_type == OBJECT_MULTI_STATE_VALUE) {
		section = "bacnet_mv";
		type = "mv";
#endif
	} else {
		return 0;
	}
	if ( ucirewrite == 0) {
		chk_mtime = ucimodtime;
#if PRINT_ENABLED
		printf("rewrite type: %s\n", type);
#endif
	} else {
		chk_mtime = check_uci_update(section, ucimodtime);
	}
	if(chk_mtime != 0) {
		sleep(1);
		ucimodtime = 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 ) {
			uci_idx = atoi(cur->idx);
#if PRINT_ENABLED
			printf("section %s idx %i \n", section, uci_idx);
#endif
			if (false) {
			}
/* update Analog Input from uci */
#if defined(AI)
			else if (update_object_type == OBJECT_ANALOG_INPUT) {
				float ai_val, ai_pval;
				ai_val = strtof(cur->value,NULL);
				ai_pval = Analog_Input_Present_Value(uci_idx);
				if ( ai_val != ai_pval ) {
					Analog_Input_Present_Value_Set(uci_idx,ai_val,16);
				}
				if (cur->Out_Of_Service == 0) {
					if (Analog_Input_Out_Of_Service(uci_idx))
						Analog_Input_Out_Of_Service_Set(uci_idx,0);
					if (Analog_Input_Reliability(uci_idx))
						Analog_Input_Reliability_Set(uci_idx,
							RELIABILITY_NO_FAULT_DETECTED);
				} else {
#if PRINT_ENABLED
					printf("idx %s ",cur->idx);
					printf("Out_Of_Service\n");
#endif
					Analog_Input_Out_Of_Service_Set(uci_idx,1);
					Analog_Input_Reliability_Set(uci_idx,
						RELIABILITY_COMMUNICATION_FAILURE);
				}
			}
#endif
/* update Analog Output from uci */
#if defined(AO)
			else if (update_object_type == OBJECT_ANALOG_OUTPUT) {
				float ao_val, ao_pval;
				ao_val = strtof(cur->value,NULL);
				ao_pval = Analog_Output_Present_Value(uci_idx);
				if ( ao_val != ao_pval ) {
					Analog_Output_Present_Value_Set(uci_idx,ao_val,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);
				}
			}
#endif
/* update Analog Value from uci */
#if defined(AV)
			else if (update_object_type == OBJECT_ANALOG_VALUE) {
				float av_val, av_pval;
				av_val = strtof(cur->value,NULL);
				av_pval = Analog_Value_Present_Value(uci_idx);
				if ( av_val != av_pval ) {
					Analog_Value_Present_Value_Set(uci_idx,av_val,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);
				}
			}
#endif
/* update Binary Input from uci */
#if defined(BI)
			else if (update_object_type == OBJECT_BINARY_INPUT) {
				int bi_val, bi_pval;
				bi_val = atoi(cur->value);
				bi_pval = Binary_Input_Present_Value(uci_idx);
				if ( bi_val != bi_pval ) {
					Binary_Input_Present_Value_Set(uci_idx,bi_val,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);
				}
			}
#endif
/* update Binary Output from uci */
#if defined(BO)
			else if (update_object_type == OBJECT_BINARY_OUTPUT) {
				int bo_val, bo_pval;
				bo_val = atoi(cur->value);
				bo_pval = Binary_Output_Present_Value(uci_idx);
				if ( bo_val != bo_pval ) {
					Binary_Output_Present_Value_Set(uci_idx,bo_val,16);
				}
				if (cur->Out_Of_Service == 0) {
					if (Binary_Output_Out_Of_Service(uci_idx))
						Binary_Output_Out_Of_Service_Set(uci_idx,0);
					if (Binary_Output_Reliability(uci_idx))
						Binary_Output_Reliability_Set(uci_idx,
							RELIABILITY_NO_FAULT_DETECTED);
				} else {
#if PRINT_ENABLED
					printf("idx %s ",cur->idx);
					printf("Out_Of_Service\n");
#endif
					Binary_Output_Out_Of_Service_Set(uci_idx,1);
					Binary_Output_Reliability_Set(uci_idx,
						RELIABILITY_COMMUNICATION_FAILURE);
				}
			}
#endif
/* update Binary Value from uci */
#if defined(BV)
			else if (update_object_type == OBJECT_BINARY_VALUE) {
				int bv_val, bv_pval;
				bv_val = atoi(cur->value);
				bv_pval = Binary_Value_Present_Value(uci_idx);
				if ( bv_val != bv_pval ) {
					Binary_Value_Present_Value_Set(uci_idx,bv_val,16);
				}
				if (cur->Out_Of_Service == 0) {
					if (Binary_Value_Out_Of_Service(uci_idx))
						Binary_Value_Out_Of_Service_Set(uci_idx,0);
					if (Binary_Value_Reliability(uci_idx))
						Binary_Value_Reliability_Set(uci_idx,
							RELIABILITY_NO_FAULT_DETECTED);
				} else {
#if PRINT_ENABLED
					printf("idx %s ",cur->idx);
					printf("Out_Of_Service\n");
#endif
					Binary_Value_Out_Of_Service_Set(uci_idx,1);
					Binary_Value_Reliability_Set(uci_idx,
						RELIABILITY_COMMUNICATION_FAILURE);
				}
			}
#endif
/* update Multistate Input from uci */
#if defined(MSI)
			else if (update_object_type == OBJECT_MULTI_STATE_INPUT) {
				int msi_val, msi_pval;
				msi_val = atoi(cur->value);
				msi_pval = Multistate_Input_Present_Value(uci_idx);
				if ( msi_val != msi_pval ) {
					Multistate_Input_Present_Value_Set(uci_idx,msi_val,16);
				}
				if (cur->Out_Of_Service == 0) {
					if (Multistate_Input_Out_Of_Service(uci_idx))
						Multistate_Input_Out_Of_Service_Set(uci_idx,0);
					if (Multistate_Input_Reliability(uci_idx))
						Multistate_Input_Reliability_Set(uci_idx,
							RELIABILITY_NO_FAULT_DETECTED);
				} else {
#if PRINT_ENABLED
					printf("idx %s ",cur->idx);
					printf("Out_Of_Service\n");
#endif
					Multistate_Input_Out_Of_Service_Set(uci_idx,1);
					Multistate_Input_Reliability_Set(uci_idx,
						RELIABILITY_COMMUNICATION_FAILURE);
				}
			}
#endif
/* update Multistate Output from uci */
#if defined(MSO)
			else if (update_object_type == OBJECT_MULTI_STATE_OUTPUT) {
				int mso_val, mso_pval;
				mso_val = atoi(cur->value);
				mso_pval = Multistate_Output_Present_Value(uci_idx);
				if ( mso_val != mso_pval ) {
					Multistate_Output_Present_Value_Set(uci_idx,mso_val,16);
				}
				if (cur->Out_Of_Service == 0) {
					if (Multistate_Output_Out_Of_Service(uci_idx))
						Multistate_Output_Out_Of_Service_Set(uci_idx,0);
					if (Multistate_Output_Reliability(uci_idx))
						Multistate_Output_Reliability_Set(uci_idx,
							RELIABILITY_NO_FAULT_DETECTED);
				} else {
#if PRINT_ENABLED
					printf("idx %s ",cur->idx);
					printf("Out_Of_Service\n");
#endif
					Multistate_Output_Out_Of_Service_Set(uci_idx,1);
					Multistate_Output_Reliability_Set(uci_idx,
						RELIABILITY_COMMUNICATION_FAILURE);
				}
			}
#endif
/* update Multistate Value from uci */
#if defined(MSV)
			else if (update_object_type == OBJECT_MULTI_STATE_VALUE) {
				int msv_val, msv_pval;
				msv_val = atoi(cur->value);
				msv_pval = Multistate_Value_Present_Value(uci_idx);
				if ( msv_val != msv_pval ) {
					Multistate_Value_Present_Value_Set(uci_idx,msv_val,16);
				}
				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);
				}
			}
#endif
		}
		ucix_cleanup(ctx);
	}
	/* update end */
	return ucimodtime;
}
Esempio n. 5
0
/* returns true if successful */
bool Analog_Value_Write_Property(
    BACNET_WRITE_PROPERTY_DATA * wp_data,
    BACNET_ERROR_CLASS * error_class,
    BACNET_ERROR_CODE * error_code)
{
    bool status = false;        /* return value */
    unsigned int object_index = 0;
    unsigned int priority = 0;
    uint8_t level = ANALOG_LEVEL_NULL;
    int len = 0;
    BACNET_APPLICATION_DATA_VALUE value;

    Analog_Value_Init();
    if (!Analog_Value_Valid_Instance(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_PRESENT_VALUE:
            if (value.tag == BACNET_APPLICATION_TAG_REAL) {
                /* Command priority 6 is reserved for use by Minimum On/Off
                   algorithm and may not be used for other purposes in any
                   object. */
                if (Analog_Value_Present_Value_Set(wp_data->object_instance,
                        value.type.Real, wp_data->priority)) {
                    status = true;
                } else if (wp_data->priority == 6) {
                    /* Command priority 6 is reserved for use by Minimum On/Off
                       algorithm and may not be used for other purposes in any
                       object. */
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
                } else {
                    *error_class = ERROR_CLASS_PROPERTY;
                    *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            } else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
                level = ANALOG_LEVEL_NULL;
                object_index =
                    Analog_Value_Instance_To_Index(wp_data->object_instance);
                priority = wp_data->priority;
                if (priority && (priority <= BACNET_MAX_PRIORITY)) {
                    priority--;
                    Analog_Value_Level[object_index][priority] = level;
                    /* Note: you could set the physical output here to the next
                       highest priority, or to the relinquish default if no
                       priorities are set.
                       However, if Out of Service is TRUE, then don't set the
                       physical output.  This comment may apply to the
                       main loop (i.e. check out of service before changing output) */
                    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_OUT_OF_SERVICE:
            if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
                object_index =
                    Analog_Value_Instance_To_Index(wp_data->object_instance);
                Analog_Value_Out_Of_Service[object_index] = value.type.Boolean;
                status = true;
            } 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;
}