Beispiel #1
0
/* for discovery, it must be consistent! */
unsigned Device_Object_List_Count(
    void)
{
    unsigned count = 1; /* at least 1 for device object */

/* FIXME: add objects as needed */
    count += Binary_Value_Count();
    count += Analog_Input_Count();
    count += Binary_Input_Count();
    count += Analog_Value_Count();

    return count;
}
Beispiel #2
0
/* for discovery, it must be consistent! */
bool Device_Object_List_Identifier(
    unsigned array_index,
    int *object_type,
    uint32_t * instance)
{
    bool status = false;
    unsigned object_index = 0;
    unsigned object_count = 0;

    /* device object */
    if (array_index == 1) {
        *object_type = OBJECT_DEVICE;
        *instance = Object_Instance_Number;
        status = true;
    }
    /* normalize the index since
       we know it is not the previous objects */
    /* array index starts at 1 */
    object_index = array_index - 1;
    /* 1 for the device object */
    object_count = 1;
    /* FIXME: add objects as needed */
    /* binary value objects */
    if (!status) {
        object_index -= object_count;
        object_count = Binary_Value_Count();
        /* is it a valid index for this object? */
        if (object_index < object_count) {
            *object_type = OBJECT_BINARY_VALUE;
            *instance = Binary_Value_Index_To_Instance(object_index);
            status = true;
        }
    }
    /* analog input objects */
    if (!status) {
        /* array index starts at 1, and 1 for the device object */
        object_index -= object_count;
        object_count = Analog_Value_Count();
        if (object_index < object_count) {
            *object_type = OBJECT_ANALOG_VALUE;
            *instance = Analog_Value_Index_To_Instance(object_index);
            status = true;
        }
    }
    /* analog input objects */
    if (!status) {
        /* array index starts at 1, and 1 for the device object */
        object_index -= object_count;
        object_count = Analog_Input_Count();
        if (object_index < object_count) {
            *object_type = OBJECT_ANALOG_INPUT;
            *instance = Analog_Input_Index_To_Instance(object_index);
            status = true;
        }
    }
    /* binary input objects */
    if (!status) {
        /* normalize the index since
           we know it is not the previous objects */
        object_index -= object_count;
        object_count = Binary_Input_Count();
        /* is it a valid index for this object? */
        if (object_index < object_count) {
            *object_type = OBJECT_BINARY_INPUT;
            *instance = Binary_Input_Index_To_Instance(object_index);
            status = true;
        }
    }

    return status;
}
Beispiel #3
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;
}