Exemple #1
0
void test_ReinitializeDevice(
    Test * pTest)
{
    uint8_t apdu[480] = { 0 };
    int len = 0;
    int apdu_len = 0;
    uint8_t invoke_id = 128;
    uint8_t test_invoke_id = 0;
    BACNET_REINITIALIZED_STATE state;
    BACNET_REINITIALIZED_STATE test_state;
    BACNET_CHARACTER_STRING password;
    BACNET_CHARACTER_STRING test_password;

    state = BACNET_REINIT_WARMSTART;
    characterstring_init_ansi(&password, "John 3:16");
    len = rd_encode_apdu(&apdu[0], invoke_id, state, &password);
    ct_test(pTest, len != 0);
    apdu_len = len;

    len =
        rd_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_state,
        &test_password);
    ct_test(pTest, len != -1);
    ct_test(pTest, test_invoke_id == invoke_id);
    ct_test(pTest, test_state == state);
    ct_test(pTest, characterstring_same(&test_password, &password));

    return;
}
Exemple #2
0
void testWhoHas(
    Test * pTest)
{
    BACNET_WHO_HAS_DATA data;

    data.low_limit = -1;
    data.high_limit = -1;
    data.object_name = false;
    data.object.identifier.type = OBJECT_ANALOG_INPUT;
    data.object.identifier.instance = 1;
    testWhoHasData(pTest, &data);

    for (data.low_limit = 0; data.low_limit <= BACNET_MAX_INSTANCE;
        data.low_limit += (BACNET_MAX_INSTANCE / 4)) {
        for (data.high_limit = 0; data.high_limit <= BACNET_MAX_INSTANCE;
            data.high_limit += (BACNET_MAX_INSTANCE / 4)) {
            data.object_name = false;
            for (data.object.identifier.type = OBJECT_ANALOG_INPUT;
                data.object.identifier.type <= MAX_BACNET_OBJECT_TYPE;
                data.object.identifier.type++) {
                for (data.object.identifier.instance = 1;
                    data.object.identifier.instance <= BACNET_MAX_INSTANCE;
                    data.object.identifier.instance <<= 1) {
                    testWhoHasData(pTest, &data);
                }
            }
            data.object_name = true;
            characterstring_init_ansi(&data.object.name, "patricia");
            testWhoHasData(pTest, &data);
        }
    }
}
void testLSO(
    Test * pTest)
{
    uint8_t apdu[1000];
    int len;

    BACNET_LSO_DATA data;
    BACNET_LSO_DATA rxdata;

    memset(&rxdata, 0, sizeof(rxdata));


    characterstring_init_ansi(&data.requestingSrc, "foobar");
    data.operation = LIFE_SAFETY_OP_RESET;
    data.processId = 0x1234;
    data.targetObject.instance = 0x1000;
    data.targetObject.type = OBJECT_BINARY_INPUT;

    len = lso_encode_apdu(apdu, 100, &data);

    lso_decode_service_request(&apdu[4], len, &rxdata);

    ct_test(pTest, data.operation == rxdata.operation);
    ct_test(pTest, data.processId == rxdata.processId);
    ct_test(pTest, data.targetObject.instance == rxdata.targetObject.instance);
    ct_test(pTest, data.targetObject.type == rxdata.targetObject.type);
    ct_test(pTest, memcmp(data.requestingSrc.value, rxdata.requestingSrc.value,
            rxdata.requestingSrc.length) == 0);
}
Exemple #4
0
bool Routed_Device_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
    if (object_instance == pDev->bacObj.Object_Instance_Number) {
        return characterstring_init_ansi(object_name,
                                         pDev->bacObj.Object_Name);
    }

    return false;
}
Exemple #5
0
/** Manages ReadProperty service for fields which are different for routed
 * Devices, or hands off to the default Device RP function for the rest.
 * @param rpdata [in] Structure which describes the property to be read.
 * @return The length of the apdu encoded, or BACNET_STATUS_ERROR for error or
 * BACNET_STATUS_ABORT for abort message.
 */
int Routed_Device_Read_Property_Local(
    BACNET_READ_PROPERTY_DATA * rpdata)
{
    int apdu_len = 0;   /* return value */
    BACNET_CHARACTER_STRING char_string;
    uint8_t *apdu = NULL;
    DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];

    if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
            (rpdata->application_data_len == 0)) {
        return 0;
    }
    apdu = rpdata->application_data;
    switch (rpdata->object_property) {
    case PROP_OBJECT_IDENTIFIER:
        apdu_len =
            encode_application_object_id(&apdu[0], OBJECT_DEVICE,
                                         pDev->bacObj.Object_Instance_Number);
        break;
    case PROP_OBJECT_NAME:
        characterstring_init_ansi(&char_string, pDev->bacObj.Object_Name);
        apdu_len =
            encode_application_character_string(&apdu[0], &char_string);
        break;
    case PROP_DESCRIPTION:
        characterstring_init_ansi(&char_string, pDev->Description);
        apdu_len =
            encode_application_character_string(&apdu[0], &char_string);
        break;
    case PROP_DATABASE_REVISION:
        apdu_len =
            encode_application_unsigned(&apdu[0], pDev->Database_Revision);
        break;
    default:
        apdu_len = Device_Read_Property_Local(rpdata);
        break;
    }

    return (apdu_len);
}
Exemple #6
0
/* note: the object name must be unique within this device */
bool Life_Safety_Point_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[32] = "";   /* okay for single thread */
    bool status = false;

    if (object_instance < MAX_LIFE_SAFETY_POINTS) {
        sprintf(text_string, "LS POINT %u", object_instance);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #7
0
/* note: the object name must be unique within this device */
bool Binary_Output_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[32];        /* okay for single thread */
    bool status = false;

    if (object_instance < MAX_BINARY_OUTPUTS) {
        sprintf(text_string, "BO-%lu", object_instance);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #8
0
bool bacfile_object_name(
    uint32_t instance,
    BACNET_CHARACTER_STRING * object_name)
{
    bool status = false;
    char *filename = NULL;

    filename = bacfile_name(instance);
    if (filename) {
        status = characterstring_init_ansi(object_name, filename);
    }

    return status;
}
Exemple #9
0
/* note: the object name must be unique within this device */
bool Binary_Output_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[16] = "BO-0";       /* okay for single thread */
    bool status = false;

    if (object_instance < MAX_BINARY_OUTPUTS) {
        text_string[3] = '0' + (uint8_t) object_instance;
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #10
0
/* note: the object name must be unique within this device */
bool Multistate_Output_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[32] = "";   /* okay for single thread */
    bool status = false;

    if (object_instance < MAX_MULTISTATE_OUTPUTS) {
        sprintf(text_string, "MULTISTATE OUTPUT %u", object_instance);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #11
0
bool Analog_Value_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[16] = "AV-0";       /* okay for single thread */
    bool status = false;

    if (object_instance < MAX_ANALOG_VALUES) {
        text_string[3] = '0' + (uint8_t) object_instance;
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #12
0
bool Multistate_Input_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    unsigned index = 0; /* offset from instance lookup */
    bool status = false;

    index = Multistate_Input_Instance_To_Index(object_instance);
    if (index < MAX_MULTISTATE_INPUTS) {
        status = characterstring_init_ansi(object_name, Object_Name[index]);
    }

    return status;
}
Exemple #13
0
bool Schedule_Object_Name(uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[32] = "";   /* okay for single thread */
    unsigned int index;
    bool status = false;

    index = Schedule_Instance_To_Index(object_instance);
    if (index < MAX_SCHEDULES) {
        sprintf(text_string, "SCHEDULE %lu", (unsigned long) index);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
/* note: the object name must be unique within this device */
bool Binary_Value_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[32] = "";   /* okay for single thread */
    bool status = false;

    if (object_instance < MAX_BINARY_VALUES) {
        sprintf(text_string, "BINARY VALUE %lu",
            (unsigned long) object_instance);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
/* note: the object name must be unique within this device */
bool Credential_Data_Input_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[32] = "";   /* okay for single thread */
    bool status = false;

    if (object_instance < MAX_CREDENTIAL_DATA_INPUTS) {
        sprintf(text_string, "CREDENTIAL DATA INPUT %lu",
            (unsigned long) object_instance);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
bool Notification_Class_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[32] = "";   /* okay for single thread */
    unsigned int index;
    bool status = false;

    index = Notification_Class_Instance_To_Index(object_instance);
    if (index < MAX_NOTIFICATION_CLASSES) {
        sprintf(text_string, "NOTIFICATION CLASS %lu", (unsigned long) index);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #17
0
/**
 * For a given object instance-number, loads the object-name into
 * a characterstring. Note that the object name must be unique
 * within this device.
 *
 * @param  object_instance - object-instance number of the object
 * @param  object_name - holds the object-name retrieved
 *
 * @return  true if object-name was retrieved
 */
bool Integer_Value_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    char text_string[32] = "";
    unsigned int index;
    bool status = false;

    index = Integer_Value_Instance_To_Index(object_instance);
    if (index < MAX_INTEGER_VALUES) {
        sprintf(text_string, "ANALOG VALUE %lu", (unsigned long) object_instance);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #18
0
/** Initialize the Device Object.
 Initialize the group of object helper functions for any supported Object.
 Initialize each of the Device Object child Object instances.
 * @ingroup ObjIntf
 * @param object_table [in,out] array of structure with object functions.
 *  Each Child Object must provide some implementation of each of these
 *  functions in order to properly support the default handlers.
 */
void Device_Init(
    object_functions_t * object_table)
{
    struct object_functions *pObject = NULL;

    characterstring_init_ansi(&My_Object_Name, "SimpleClient");
    /* we don't use the object table passed in */
    (void) object_table;
    pObject = &Object_Table[0];
    while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
        if (pObject->Object_Init) {
            pObject->Object_Init();
        }
        pObject++;
    }
}
Exemple #19
0
bool Analog_Input_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    static char text_string[32];        /* okay for single thread */
    bool status = false;
	unsigned index = 0;

	index = Analog_Input_Instance_To_Index(object_instance);
	if (index < MAX_ANALOG_INPUTS) {
        sprintf(text_string, "AI-%lu", object_instance);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #20
0
/**
 * For a given object instance-number, loads the object-name into
 * a characterstring. Note that the object name must be unique
 * within this device.
 *
 * @param  object_instance - object-instance number of the object
 * @param  object_name - holds the object-name retrieved
 *
 * @return  true if object-name was retrieved
 */
bool Lighting_Output_Object_Name(
    uint32_t object_instance,
    BACNET_CHARACTER_STRING * object_name)
{
    char text_string[32] = "";
    bool status = false;
    unsigned index = 0;

    index = Lighting_Output_Instance_To_Index(object_instance);
    if (index < MAX_LIGHTING_OUTPUTS) {
        sprintf(text_string, "LIGHTING OUTPUT %lu",
            (unsigned long) object_instance);
        status = characterstring_init_ansi(object_name, text_string);
    }

    return status;
}
Exemple #21
0
void bacnet_name(uint16_t offset,
    BACNET_CHARACTER_STRING * char_string,
    char *default_string)
{
    uint8_t encoding = 0;
    uint8_t length = 0;
    char name[NVM_NAME_SIZE + 1] = "";

    nvm_read(NVM_NAME_ENCODING(offset), &encoding, 1);
    nvm_read(NVM_NAME_LENGTH(offset), &length, 1);
    nvm_read(NVM_NAME_STRING(offset), (uint8_t *) & name[0], NVM_NAME_SIZE);
    if (bacnet_name_isvalid(encoding, length, name)) {
        characterstring_init(char_string, encoding, &name[0], length);
    } else if (default_string) {
        characterstring_init_ansi(char_string, default_string);
    }
}
Exemple #22
0
/** Send a Who-Has request for a device which has a named Object.
 * @ingroup DMDOB
 * If low_limit and high_limit both are -1, then the device ID range is unlimited.
 * If low_limit and high_limit have the same non-negative value, then only
 * that device will respond.
 * Otherwise, low_limit must be less than high_limit for a range.
 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
 * @param object_name [in] The Name of the desired Object.
 */
void Send_WhoHas_Name(
    int32_t low_limit,
    int32_t high_limit,
    const char *object_name)
{
    int len = 0;
    int pdu_len = 0;
    BACNET_ADDRESS dest;
    int bytes_sent = 0;
    BACNET_WHO_HAS_DATA data;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;

    /* if we are forbidden to send, don't send! */
    if (!dcc_communication_enabled())
        return;
    /* Who-Has is a global broadcast */
    datalink_get_broadcast_address(&dest);
    datalink_get_my_address(&my_address);
    /* encode the NPDU portion of the packet */
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
        &npdu_data);

    /* encode the APDU portion of the packet */
    data.low_limit = low_limit;
    data.high_limit = high_limit;
    data.is_object_name = true;
    characterstring_init_ansi(&data.object.name, object_name);
    len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
    pdu_len += len;
    /* send the data */
    bytes_sent =
        datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0)
        fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n",
            strerror(errno));
#endif
}
Exemple #23
0
void Device_Init(
    object_functions_t * object_table)
{
    struct my_object_functions *pObject = NULL;

    /* we don't use the object table passed in
       since there is extra stuff we don't need in there. */
    (void) object_table;
    /* our local object table */
    pObject = &Object_Table[0];
    while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
        if (pObject->Object_Init) {
            pObject->Object_Init();
        }
        pObject++;
    }
    dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
    Object_Instance_Number = 12345;
    characterstring_init_ansi(&My_Object_Name, "ARM7 Demo Device");
}
Exemple #24
0
void testIHave(
    Test * pTest)
{
    BACNET_I_HAVE_DATA data;

    characterstring_init_ansi(&data.object_name, "Patricia - my love!");
    data.device_id.type = OBJECT_DEVICE;
    for (data.device_id.instance = 1;
        data.device_id.instance <= BACNET_MAX_INSTANCE;
        data.device_id.instance <<= 1) {
        for (data.object_id.type = OBJECT_ANALOG_INPUT;
            data.object_id.type < MAX_BACNET_OBJECT_TYPE;
            data.object_id.type++) {
            for (data.object_id.instance = 1;
                data.object_id.instance <= BACNET_MAX_INSTANCE;
                data.object_id.instance <<= 1) {
                testIHaveData(pTest, &data);
            }
        }
    }
}
Exemple #25
0
/* find a specific device, or use -1 for limit if you want unlimited */
void Send_I_Have(
    uint32_t device_id,
    BACNET_OBJECT_TYPE object_type,
    uint32_t object_instance,
    char *object_name)
{
    int len = 0;
    int pdu_len = 0;
    BACNET_ADDRESS dest;
    int bytes_sent = 0;
    BACNET_I_HAVE_DATA data;
    BACNET_NPDU_DATA npdu_data;

    /* if we are forbidden to send, don't send! */
    if (!dcc_communication_enabled())
        return;
    /* Who-Has is a global broadcast */
    datalink_get_broadcast_address(&dest);
    /* encode the NPDU portion of the packet */
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, NULL, &npdu_data);
    /* encode the APDU portion of the packet */
    data.device_id.type = OBJECT_DEVICE;
    data.device_id.instance = device_id;
    data.object_id.type = object_type;
    data.object_id.instance = object_instance;
    characterstring_init_ansi(&data.object_name, object_name);
    len = ihave_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
    pdu_len += len;
    /* send the data */
    bytes_sent =
        datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0)
        fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n",
            strerror(errno));
#endif
}
Exemple #26
0
void Device_Init(
    object_functions_t * object_table)
{
    struct my_object_functions *pObject = NULL;

    /* we don't use the object table passed in
       since there is extra stuff we don't need in there. */
    (void) object_table;
    /* our local object table */
    pObject = &Object_Table[0];
    while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
        if (pObject->Object_Init) {
            pObject->Object_Init();
        }
        pObject++;
    }
    dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
    if (Object_Instance_Number >= BACNET_MAX_INSTANCE) {
        Object_Instance_Number = 103;
        srand(Object_Instance_Number);
    }
    characterstring_init_ansi(&My_Object_Name, "stm32-design-challenge-103");
}
Exemple #27
0
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error */
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
{
    int apdu_len = 0;   /* return value */
    int len = 0;        /* apdu len intermediate value */
    BACNET_BIT_STRING bit_string = { 0 };
    BACNET_CHARACTER_STRING char_string = { 0 };
    unsigned i = 0;
    int object_type = 0;
    uint32_t instance = 0;
    unsigned count = 0;
    uint8_t *apdu = NULL;
    struct my_object_functions *pObject = NULL;

    if ((rpdata->application_data == NULL) ||
        (rpdata->application_data_len == 0)) {
        return 0;
    }
    apdu = rpdata->application_data;
    switch ((int) rpdata->object_property) {
        case PROP_OBJECT_IDENTIFIER:
            apdu_len =
                encode_application_object_id(&apdu[0], rpdata->object_type,
                rpdata->object_instance);
            break;
        case PROP_OBJECT_NAME:
            Device_Object_Name(rpdata->object_instance, &char_string);
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_OBJECT_TYPE:
            apdu_len =
                encode_application_enumerated(&apdu[0], rpdata->object_type);
            break;
        case PROP_DESCRIPTION:
            bacnet_name(NVM_DEVICE_DESCRIPTION, &char_string,
                "default description");
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_LOCATION:
            bacnet_name(NVM_DEVICE_LOCATION, &char_string,
                "default location");
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_SYSTEM_STATUS:
            apdu_len =
                encode_application_enumerated(&apdu[0],
                Device_System_Status());
            break;
        case PROP_VENDOR_NAME:
            characterstring_init_ansi(&char_string, Device_Vendor_Name());
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_VENDOR_IDENTIFIER:
            apdu_len = encode_application_unsigned(&apdu[0], BACNET_VENDOR_ID);
            break;
        case PROP_MODEL_NAME:
            characterstring_init_ansi(&char_string, Device_Model_Name());
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_FIRMWARE_REVISION:
            characterstring_init_ansi(&char_string,
                Device_Firmware_Revision());
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_APPLICATION_SOFTWARE_VERSION:
            characterstring_init_ansi(&char_string,
                Device_Application_Software_Version());
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_PROTOCOL_VERSION:
            apdu_len =
                encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_VERSION);
            break;
        case PROP_PROTOCOL_REVISION:
            apdu_len =
                encode_application_unsigned(&apdu[0],
                BACNET_PROTOCOL_REVISION);
            break;
        case PROP_PROTOCOL_SERVICES_SUPPORTED:
            /* Note: list of services that are executed, not initiated. */
            bitstring_init(&bit_string);
            for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
                /* automatic lookup based on handlers set */
                bitstring_set_bit(&bit_string, (uint8_t) i,
                    apdu_service_supported((BACNET_SERVICES_SUPPORTED) i));
            }
            apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
            break;
        case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
            /* Note: this is the list of objects that can be in this device,
               not a list of objects that this device can access */
            bitstring_init(&bit_string);
            for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
                /* initialize all the object types to not-supported */
                bitstring_set_bit(&bit_string, (uint8_t) i, false);
            }
            /* set the object types with objects to supported */
            i = 0;
            pObject = &Object_Table[i];
            while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
                if ((pObject->Object_Count) && (pObject->Object_Count() > 0)) {
                    bitstring_set_bit(&bit_string, pObject->Object_Type, true);
                }
                pObject++;
            }
            apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
            break;
        case PROP_OBJECT_LIST:
            count = Device_Object_List_Count();
            /* Array element zero is the number of objects in the list */
            if (rpdata->array_index == 0)
                apdu_len = encode_application_unsigned(&apdu[0], count);
            /* if no index was specified, then try to encode the entire list */
            /* into one packet.  Note that more than likely you will have */
            /* to return an error if the number of encoded objects exceeds */
            /* your maximum APDU size. */
            else if (rpdata->array_index == BACNET_ARRAY_ALL) {
                for (i = 1; i <= count; i++) {
                    if (Device_Object_List_Identifier(i, &object_type,
                            &instance)) {
                        len =
                            encode_application_object_id(&apdu[apdu_len],
                            object_type, instance);
                        apdu_len += len;
                        /* assume next one is the same size as this one */
                        /* can we all fit into the APDU? */
                        if ((apdu_len + len) >= MAX_APDU) {
                            /* Abort response */
                            rpdata->error_code =
                                ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
                            apdu_len = BACNET_STATUS_ABORT;
                            break;
                        }
                    } else {
                        /* error: internal error? */
                        rpdata->error_class = ERROR_CLASS_SERVICES;
                        rpdata->error_code = ERROR_CODE_OTHER;
                        apdu_len = BACNET_STATUS_ERROR;
                        break;
                    }
                }
            } else {
                if (Device_Object_List_Identifier(rpdata->array_index,
                        &object_type, &instance))
                    apdu_len =
                        encode_application_object_id(&apdu[0], object_type,
                        instance);
                else {
                    rpdata->error_class = ERROR_CLASS_PROPERTY;
                    rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
                    apdu_len = BACNET_STATUS_ERROR;
                }
            }
            break;
        case PROP_MAX_APDU_LENGTH_ACCEPTED:
            apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
            break;
        case PROP_SEGMENTATION_SUPPORTED:
            apdu_len =
                encode_application_enumerated(&apdu[0],
                Device_Segmentation_Supported());
            break;
        case PROP_APDU_TIMEOUT:
            apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
            break;
        case PROP_NUMBER_OF_APDU_RETRIES:
            apdu_len = encode_application_unsigned(&apdu[0], apdu_retries());
            break;
        case PROP_DEVICE_ADDRESS_BINDING:
            /* FIXME: encode the list here, if it exists */
            break;
        case PROP_DATABASE_REVISION:
            apdu_len =
                encode_application_unsigned(&apdu[0],
                Device_Database_Revision());
            break;
        case PROP_MAX_INFO_FRAMES:
            apdu_len =
                encode_application_unsigned(&apdu[0],
                dlmstp_max_info_frames());
            break;
        case PROP_MAX_MASTER:
            apdu_len =
                encode_application_unsigned(&apdu[0], dlmstp_max_master());
            break;
        case 512:
            apdu_len = encode_application_unsigned(&apdu[0], stack_size());
            break;
        case 513:
            apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
            break;
        default:
            rpdata->error_class = ERROR_CLASS_PROPERTY;
            rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
            apdu_len = BACNET_STATUS_ERROR;
            break;
    }
    /*  only array properties can have array options */
    if ((apdu_len >= 0) && (rpdata->object_property != PROP_OBJECT_LIST) &&
        (rpdata->array_index != BACNET_ARRAY_ALL)) {
        rpdata->error_class = ERROR_CLASS_PROPERTY;
        rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
        apdu_len = BACNET_STATUS_ERROR;
    }

    return apdu_len;
}
Exemple #28
0
/* assumption - object already exists, and has been bounds checked */
int Binary_Input_Encode_Property_APDU(
    uint8_t * apdu,
    uint32_t object_instance,
    BACNET_PROPERTY_ID property,
    int32_t array_index,
    BACNET_ERROR_CLASS * error_class,
    BACNET_ERROR_CODE * error_code)
{
    int apdu_len = 0;   /* return value */
    BACNET_BIT_STRING bit_string;
    BACNET_CHARACTER_STRING char_string;
    BACNET_POLARITY polarity = POLARITY_NORMAL;
    BACNET_BINARY_PV value = BINARY_INACTIVE;


    (void) array_index;
    Binary_Input_Initialize();
    switch (property) {
        case PROP_OBJECT_IDENTIFIER:
            apdu_len =
                encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT,
                object_instance);
            break;
        case PROP_OBJECT_NAME:
        case PROP_DESCRIPTION:
            /* note: object name must be unique in our device */
            characterstring_init_ansi(&char_string,
                Binary_Input_Name(object_instance));
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_OBJECT_TYPE:
            apdu_len =
                encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT);
            break;
        case PROP_PRESENT_VALUE:
            value = Binary_Input_Present_Value(object_instance);
            apdu_len = encode_application_enumerated(&apdu[0], value);
            break;
        case PROP_STATUS_FLAGS:
            /* note: see the details in the standard on how to use these */
            bitstring_init(&bit_string);
            bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
            bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
            bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
            bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
            apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
            break;
        case PROP_EVENT_STATE:
            /* note: see the details in the standard on how to use this */
            apdu_len =
                encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
            break;
        case PROP_OUT_OF_SERVICE:
            apdu_len = encode_application_boolean(&apdu[0], false);
            break;
        case PROP_POLARITY:
            apdu_len = encode_application_enumerated(&apdu[0], polarity);
            break;
        default:
            *error_class = ERROR_CLASS_PROPERTY;
            *error_code = ERROR_CODE_UNKNOWN_PROPERTY;
            apdu_len = -1;
            break;
    }

    return apdu_len;
}
Exemple #29
0
void testAlarmAck(
    Test * pTest)
{
    BACNET_ALARM_ACK_DATA testAlarmAckIn;
    BACNET_ALARM_ACK_DATA testAlarmAckOut;

    uint8_t buffer[MAX_APDU];
    int inLen;
    int outLen;

    testAlarmAckIn.ackProcessIdentifier = 0x1234;
    characterstring_init_ansi(&testAlarmAckIn.ackSource, "This is a test");
    testAlarmAckIn.ackTimeStamp.tag = TIME_STAMP_SEQUENCE;
    testAlarmAckIn.ackTimeStamp.value.sequenceNum = 0x4331;
    testAlarmAckIn.eventObjectIdentifier.instance = 567;
    testAlarmAckIn.eventObjectIdentifier.type = OBJECT_DEVICE;
    testAlarmAckIn.eventTimeStamp.tag = TIME_STAMP_TIME;
    testAlarmAckIn.eventTimeStamp.value.time.hour = 10;
    testAlarmAckIn.eventTimeStamp.value.time.min = 11;
    testAlarmAckIn.eventTimeStamp.value.time.sec = 12;
    testAlarmAckIn.eventTimeStamp.value.time.hundredths = 14;
    testAlarmAckIn.eventStateAcked = EVENT_STATE_OFFNORMAL;

    memset(&testAlarmAckOut, 0, sizeof(testAlarmAckOut));


    inLen = alarm_ack_encode_service_request(buffer, &testAlarmAckIn);
    outLen = alarm_ack_decode_service_request(buffer, inLen, &testAlarmAckOut);

    ct_test(pTest, inLen == outLen);

    ct_test(pTest,
            testAlarmAckIn.ackProcessIdentifier ==
            testAlarmAckOut.ackProcessIdentifier);

    ct_test(pTest,
            testAlarmAckIn.ackTimeStamp.tag == testAlarmAckOut.ackTimeStamp.tag);
    ct_test(pTest,
            testAlarmAckIn.ackTimeStamp.value.sequenceNum ==
            testAlarmAckOut.ackTimeStamp.value.sequenceNum);

    ct_test(pTest,
            testAlarmAckIn.ackProcessIdentifier ==
            testAlarmAckOut.ackProcessIdentifier);

    ct_test(pTest,
            testAlarmAckIn.eventObjectIdentifier.instance ==
            testAlarmAckOut.eventObjectIdentifier.instance);
    ct_test(pTest,
            testAlarmAckIn.eventObjectIdentifier.type ==
            testAlarmAckOut.eventObjectIdentifier.type);

    ct_test(pTest,
            testAlarmAckIn.eventTimeStamp.tag ==
            testAlarmAckOut.eventTimeStamp.tag);
    ct_test(pTest,
            testAlarmAckIn.eventTimeStamp.value.time.hour ==
            testAlarmAckOut.eventTimeStamp.value.time.hour);
    ct_test(pTest,
            testAlarmAckIn.eventTimeStamp.value.time.min ==
            testAlarmAckOut.eventTimeStamp.value.time.min);
    ct_test(pTest,
            testAlarmAckIn.eventTimeStamp.value.time.sec ==
            testAlarmAckOut.eventTimeStamp.value.time.sec);
    ct_test(pTest,
            testAlarmAckIn.eventTimeStamp.value.time.hundredths ==
            testAlarmAckOut.eventTimeStamp.value.time.hundredths);

    ct_test(pTest,
            testAlarmAckIn.eventStateAcked == testAlarmAckOut.eventStateAcked);

}
Exemple #30
0
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Multistate_Input_Read_Property(
    BACNET_READ_PROPERTY_DATA * rpdata)
{
    int len = 0;
    int apdu_len = 0;   /* return value */
    BACNET_BIT_STRING bit_string;
    BACNET_CHARACTER_STRING char_string;
    uint32_t present_value = 0;
    unsigned i = 0;
    uint32_t max_states = 0;
    bool state = false;
    uint8_t *apdu = NULL;

    if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
        (rpdata->application_data_len == 0)) {
        return 0;
    }
    apdu = rpdata->application_data;
    switch (rpdata->object_property) {
        case PROP_OBJECT_IDENTIFIER:
            apdu_len =
                encode_application_object_id(&apdu[0],
                OBJECT_MULTI_STATE_INPUT, rpdata->object_instance);
            break;
            /* note: Name and Description don't have to be the same.
               You could make Description writable and different */
        case PROP_OBJECT_NAME:
            Multistate_Input_Object_Name(rpdata->object_instance,
                &char_string);
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_DESCRIPTION:
            characterstring_init_ansi(&char_string,
                Multistate_Input_Description(rpdata->object_instance));
            apdu_len =
                encode_application_character_string(&apdu[0], &char_string);
            break;
        case PROP_OBJECT_TYPE:
            apdu_len =
                encode_application_enumerated(&apdu[0],
                OBJECT_MULTI_STATE_INPUT);
            break;
        case PROP_PRESENT_VALUE:
            present_value =
                Multistate_Input_Present_Value(rpdata->object_instance);
            apdu_len = encode_application_unsigned(&apdu[0], present_value);
            break;
        case PROP_STATUS_FLAGS:
            /* note: see the details in the standard on how to use these */
            bitstring_init(&bit_string);
            bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
            bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
            bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
            if (Multistate_Input_Out_Of_Service(rpdata->object_instance)) {
                bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE,
                    true);
            } else {
                bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE,
                    false);
            }
            apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
            break;
        case PROP_EVENT_STATE:
            /* note: see the details in the standard on how to use this */
            apdu_len =
                encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
            break;
        case PROP_OUT_OF_SERVICE:
            state = Multistate_Input_Out_Of_Service(rpdata->object_instance);
            apdu_len = encode_application_boolean(&apdu[0], state);
            break;
        case PROP_NUMBER_OF_STATES:
            apdu_len =
                encode_application_unsigned(&apdu[apdu_len],
                Multistate_Input_Max_States(rpdata->object_instance));
            break;
        case PROP_STATE_TEXT:
            if (rpdata->array_index == 0) {
                /* Array element zero is the number of elements in the array */
                apdu_len =
                    encode_application_unsigned(&apdu[0],
                    Multistate_Input_Max_States(rpdata->object_instance));
            } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
                /* if no index was specified, then try to encode the entire list */
                /* into one packet. */
                max_states =
                    Multistate_Input_Max_States(rpdata->object_instance);
                for (i = 1; i <= max_states; i++) {
                    characterstring_init_ansi(&char_string,
                        Multistate_Input_State_Text(rpdata->object_instance,
                            i));
                    /* FIXME: this might go beyond MAX_APDU length! */
                    len =
                        encode_application_character_string(&apdu[apdu_len],
                        &char_string);
                    /* add it if we have room */
                    if ((apdu_len + len) < MAX_APDU) {
                        apdu_len += len;
                    } else {
                        rpdata->error_class = ERROR_CLASS_SERVICES;
                        rpdata->error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
                        apdu_len = BACNET_STATUS_ERROR;
                        break;
                    }
                }
            } else {
                max_states =
                    Multistate_Input_Max_States(rpdata->object_instance);
                if (rpdata->array_index <= max_states) {
                    characterstring_init_ansi(&char_string,
                        Multistate_Input_State_Text(rpdata->object_instance,
                            rpdata->array_index));
                    apdu_len =
                        encode_application_character_string(&apdu[0],
                        &char_string);
                } else {
                    rpdata->error_class = ERROR_CLASS_PROPERTY;
                    rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
                    apdu_len = BACNET_STATUS_ERROR;
                }
            }
            break;
        default:
            rpdata->error_class = ERROR_CLASS_PROPERTY;
            rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
            apdu_len = BACNET_STATUS_ERROR;
            break;
    }
    /*  only array properties can have array options */
    if ((apdu_len >= 0) && (rpdata->object_property != PROP_STATE_TEXT) &&
        (rpdata->array_index != BACNET_ARRAY_ALL)) {
        rpdata->error_class = ERROR_CLASS_PROPERTY;
        rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
        apdu_len = BACNET_STATUS_ERROR;
    }

    return apdu_len;
}