Added arguments to bacepics which let you specify a source port to use (besides 0xBAC0) and a target MAC to use.
Combining these lets you run bacepics against the localhost's Device at port 0xBAC0. One small change in dlenv_init() to support this (don't force source port to 0xBAC0 if that's not what we want).
This commit is contained in:
@@ -40,11 +40,23 @@
|
|||||||
* each of those Objects.
|
* each of those Objects.
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
* ./bacepics [-v] 1234
|
* bacepics [-v] [-p sport] [-t target_mac] device-instance
|
||||||
|
* -v: show values instead of '?'
|
||||||
|
* -p: Use sport for "my" port, instead of 0xBAC0 (BACnet/IP only)
|
||||||
|
* Allows you to communicate with a localhost target.
|
||||||
|
* -t: declare target's MAC instead of using Who-Is to bind to
|
||||||
|
* device-instance. Format is "C0:A8:00:18:BA:C0" (as usual)
|
||||||
*
|
*
|
||||||
* - where the device instance to be addressed is 1234,
|
* Examples:
|
||||||
* - and the optional -v prints values out rather than the '?' that
|
* ./bacepics -v 1234
|
||||||
|
* where the device instance to be addressed is 1234
|
||||||
|
* and the optional -v prints values out rather than the '?' that
|
||||||
* the EPICS format for VTS3 wants.
|
* the EPICS format for VTS3 wants.
|
||||||
|
* ./bacepics -p 0xBAC1 -t "7F:0:0:1:BA:C0" 4194303
|
||||||
|
* communicates with the BACnet device on localhost (127.0.0.1), using
|
||||||
|
* port 47809 as "my" source port so it doesn't conflict with
|
||||||
|
* the device's port 47808.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* The tool follows an optimal approach which will use efficient communication
|
* The tool follows an optimal approach which will use efficient communication
|
||||||
* means if available or else fall back to simple-minded methods.
|
* means if available or else fall back to simple-minded methods.
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
|||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
||||||
static BACNET_ADDRESS Target_Address;
|
static BACNET_ADDRESS Target_Address;
|
||||||
/* = { 6, { 127, 0, 0, 1, 0xBA, 0xC0, 0 }, 0 }; loopback address to talk to myself */
|
/* = { 6, { 127, 0, 0, 1, 0xBA, 0xC0, 0 }, 0 }; loopback address to talk to myself */
|
||||||
|
static uint16_t My_BIP_Port = 0; /* If set, use this as the source port. */
|
||||||
|
static bool Provided_Targ_MAC = false;
|
||||||
|
|
||||||
/* any errors are picked up in main loop */
|
/* any errors are picked up in main loop */
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
@@ -719,13 +721,19 @@ void PrintUsage(
|
|||||||
{
|
{
|
||||||
printf("bacepics -- Generates Object and Property List for EPICS \r\n");
|
printf("bacepics -- Generates Object and Property List for EPICS \r\n");
|
||||||
printf("Usage: \r\n");
|
printf("Usage: \r\n");
|
||||||
printf(" bacepics [-v] device-instance \r\n");
|
printf(" bacepics [-v] [-p sport] [-t target_mac] device-instance \r\n");
|
||||||
printf(" Use the -v option to show values instead of '?' \r\n\r\n");
|
printf(" -v: show values instead of '?' \r\n");
|
||||||
|
printf(" -p: Use sport for \"my\" port, instead of 0xBAC0 (BACnet/IP only) \r\n");
|
||||||
|
printf(" Allows you to communicate with a localhost target. \r\n");
|
||||||
|
printf(" -t: declare target's MAC instead of using Who-Is to bind to \r\n");
|
||||||
|
printf(" device-instance. Format is \"C0:A8:00:18:BA:C0\" (as usual) \r\n");
|
||||||
|
printf("\r\n");
|
||||||
printf("Insert the output in your EPICS file as the last section: \r\n");
|
printf("Insert the output in your EPICS file as the last section: \r\n");
|
||||||
printf("\"List of Objects in test device:\" \r\n");
|
printf("\"List of Objects in test device:\" \r\n");
|
||||||
printf("before the final statement: \r\n");
|
printf("before the final statement: \r\n");
|
||||||
printf
|
printf
|
||||||
("\"End of BACnet Protocol Implementation Conformance Statement\" \r\n");
|
("\"End of BACnet Protocol Implementation Conformance Statement\" \r\n");
|
||||||
|
printf("\r\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,10 +753,41 @@ int CheckCommandLineArgs(
|
|||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
char *anArg = argv[i];
|
char *anArg = argv[i];
|
||||||
if (anArg[0] == '-') {
|
if (anArg[0] == '-') {
|
||||||
if (anArg[1] == 'v')
|
switch ( anArg[1] )
|
||||||
|
{
|
||||||
|
case 'v':
|
||||||
ShowValues = true;
|
ShowValues = true;
|
||||||
else
|
break;
|
||||||
|
case 'p':
|
||||||
|
if ( ++i < argc )
|
||||||
|
My_BIP_Port = (uint16_t) strtol(argv[i], NULL, 0);
|
||||||
|
/* Used strtol so sport can be either 0xBAC0 or 47808 */
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
if ( ++i < argc )
|
||||||
|
{
|
||||||
|
uint8_t *mac = Target_Address.mac;
|
||||||
|
/* The %hhx specifies unsigned char */
|
||||||
|
Target_Address.mac_len = sscanf( argv[i],
|
||||||
|
"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mac[0],
|
||||||
|
&mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
|
||||||
|
if ( Target_Address.mac_len == 6 ) /* success */
|
||||||
|
{
|
||||||
|
Target_Address.net = 0;
|
||||||
|
Target_Address.len = 0; /* No src address */
|
||||||
|
Provided_Targ_MAC = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf( "ERROR: invalid Target MAC %s \r\n", argv[i] );
|
||||||
|
/* And fall through to PrintUsage */
|
||||||
|
}
|
||||||
|
/* Either break or fall through, as above */
|
||||||
|
/* break; */
|
||||||
|
default:
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* decode the Target Device Instance parameter */
|
/* decode the Target Device Instance parameter */
|
||||||
Target_Device_Object_Instance = strtol(anArg, NULL, 0);
|
Target_Device_Object_Instance = strtol(anArg, NULL, 0);
|
||||||
@@ -824,24 +863,37 @@ int main(
|
|||||||
/* setup my info */
|
/* setup my info */
|
||||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||||
Object_List = Keylist_Create();
|
Object_List = Keylist_Create();
|
||||||
|
/* For BACnet/IP, we might have set a different port for "me", so
|
||||||
|
* (eg) we could talk to a BACnet/IP device on our same interface.
|
||||||
|
* My_BIP_Port will be non-zero in this case.
|
||||||
|
*/
|
||||||
|
if ( My_BIP_Port > 0 )
|
||||||
|
bip_set_port( My_BIP_Port );
|
||||||
address_init();
|
address_init();
|
||||||
Init_Service_Handlers();
|
Init_Service_Handlers();
|
||||||
dlenv_init();
|
dlenv_init();
|
||||||
/* bip_set_port( 0xBAC0 ); Set back to std BIP port */
|
|
||||||
/* configure the timeout values */
|
/* configure the timeout values */
|
||||||
current_seconds = time(NULL);
|
current_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
|
||||||
|
if ( My_BIP_Port > 0 )
|
||||||
|
bip_set_port( 0xBAC0 ); /* Set back to std BACnet/IP port */
|
||||||
|
/* try to bind with the target device */
|
||||||
found =
|
found =
|
||||||
address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
||||||
&Target_Address);
|
&Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
if ( Provided_Targ_MAC ) {
|
||||||
Target_Device_Object_Instance);
|
/* Update by adding the MAC address */
|
||||||
/* In an Alternate universe, where we talk to ourselves:
|
if ( max_apdu == 0 )
|
||||||
* address_add_binding( Target_Device_Object_Instance, max_apdu,
|
max_apdu = MAX_APDU; /* Whatever set for this datalink. */
|
||||||
* &Target_Address);
|
address_add_binding( Target_Device_Object_Instance, max_apdu,
|
||||||
*/
|
&Target_Address);
|
||||||
|
} else {
|
||||||
|
Send_WhoIs(Target_Device_Object_Instance,
|
||||||
|
Target_Device_Object_Instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf("List of Objects in test device:\r\n");
|
printf("List of Objects in test device:\r\n");
|
||||||
/* Print Opening brace, then kick off the Device Object */
|
/* Print Opening brace, then kick off the Device Object */
|
||||||
|
|||||||
@@ -92,7 +92,14 @@ void dlenv_init(
|
|||||||
if (pEnv) {
|
if (pEnv) {
|
||||||
bip_set_port((uint16_t)strtol(pEnv, NULL, 0));
|
bip_set_port((uint16_t)strtol(pEnv, NULL, 0));
|
||||||
} else {
|
} else {
|
||||||
bip_set_port(0xBAC0);
|
/* BIP_Port is statically initialized to 0xBAC0,
|
||||||
|
* so if it is different, then it was programmatically altered,
|
||||||
|
* and we shouldn't just stomp on it here.
|
||||||
|
* Unless it is set below 1024, since:
|
||||||
|
* "The range for well-known ports managed by the IANA is 0-1023."
|
||||||
|
*/
|
||||||
|
if ( bip_get_port() < 1024 )
|
||||||
|
bip_set_port(0xBAC0);
|
||||||
}
|
}
|
||||||
#elif defined(BACDL_MSTP)
|
#elif defined(BACDL_MSTP)
|
||||||
pEnv = getenv("BACNET_MAX_INFO_FRAMES");
|
pEnv = getenv("BACNET_MAX_INFO_FRAMES");
|
||||||
|
|||||||
Reference in New Issue
Block a user