Esempio n. 1
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    time_t total_seconds = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    BACNET_ADDRESS dest;
    int argi;

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

    datalink_get_broadcast_address(&dest);

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

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

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

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

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

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

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

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

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

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

    return 0;
}
Esempio n. 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;
    int fileStartPosition = 0;
    unsigned requestedOctetCount = 0;
    uint8_t invoke_id = 0;
    bool found = false;
    uint16_t my_max_apdu = 0;

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

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

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

    if (Error_Detected) {
        return 1;
    }

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

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

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

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

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

    return 0;
}
Esempio n. 5
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 100;     /* milliseconds */
    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;
}
Esempio n. 6
0
int main(
    int argc,
    char *argv[])
{
    BACNET_ADDRESS src = {
        0
    };  /* address where message came from */
    uint16_t pdu_len = 0;
    unsigned timeout = 10;      /* milliseconds */
    unsigned max_apdu = 0;
    time_t elapsed_seconds = 0;
    time_t last_seconds = 0;
    time_t current_seconds = 0;
    time_t timeout_seconds = 0;
    time_t delta_seconds = 0;
    bool found = false;
    char *filename = NULL;
    char *value_string = NULL;
    bool status = false;
    int args_remaining = 0, tag_value_arg = 0, i = 0;
    BACNET_APPLICATION_TAG property_tag;
    uint8_t context_tag = 0;
    BACNET_PRIVATE_TRANSFER_DATA private_data = { 0 };
    int len = 0;
    bool sent_message = false;

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

    if (Error_Detected)
        return 1;
    return 0;
}