Skip to content

Commit 6c9124a

Browse files
committed
improve BACnet/IP initialization for DHCP or static address.
1 parent 4a497df commit 6c9124a

File tree

2 files changed

+89
-4
lines changed

2 files changed

+89
-4
lines changed

zephyr/samples/profiles/b-sa/prj.conf

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,34 @@ CONFIG_BACNET_BASIC_DEVICE_SHELL=y
4141
# BACnet Datalink Options
4242
CONFIG_BACDL_BIP=y
4343
CONFIG_BACDL_BIP_PORT=47808
44-
CONFIG_BACDL_BIP_ADDRESS_INDEX=0
44+
# don't define index if you want to use the default interface
45+
# note: with DHCP and AutoIP enabled, index 0=AutoIP, 1=DHCP
46+
CONFIG_BACDL_BIP_ADDRESS_INDEX=1
4547

4648
# networking
4749
CONFIG_NETWORKING=y
50+
CONFIG_NET_L2_ETHERNET=y
4851
#CONFIG_NET_ARP=y
4952
#CONFIG_NET_TCP=y
5053
CONFIG_NET_UDP=y
5154
CONFIG_NET_SHELL=y
5255
CONFIG_NET_SOCKETS=y
56+
CONFIG_NET_IPV4=y
57+
CONFIG_NET_IPV4_LOG_LEVEL_DBG=n
58+
CONFIG_NET_IF_MAX_IPV4_COUNT=2
59+
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2
60+
CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT=2
5361
# Dynamic IP address
5462
CONFIG_NET_DHCPV4=y
63+
CONFIG_NET_DHCPV4_LOG_LEVEL_DBG=n
5564
CONFIG_NET_IPV4_AUTO=y
56-
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2
65+
CONFIG_NET_IPV4_AUTO_LOG_LEVEL_DBG=n
66+
CONFIG_NET_ICMPV4_LOG_LEVEL_DBG=n
67+
# read the MAC address from settings and set via net_mgmt()
68+
CONFIG_NET_MGMT_EVENT=y
69+
CONFIG_NET_L2_ETHERNET_MGMT=y
70+
CONFIG_NET_CONNECTION_MANAGER=y
71+
5772
# Static IP address pre-configuration
5873
#CONFIG_NET_CONFIG_SETTINGS=y
5974
#CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"

zephyr/subsys/bacnet_datalink/bip-init.c

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,39 @@ int bip_send_pdu(BACNET_ADDRESS *dest,
398398
return bvlc_send_pdu(dest, npdu_data, pdu, pdu_len);
399399
}
400400

401+
struct wait_data
402+
{
403+
struct k_sem sem;
404+
struct net_mgmt_event_callback cb;
405+
};
406+
407+
static void event_cb_handler(struct net_mgmt_event_callback *cb,
408+
uint32_t mgmt_event,
409+
struct net_if *iface)
410+
{
411+
struct wait_data *wait = CONTAINER_OF(cb, struct wait_data, cb);
412+
413+
if (mgmt_event == cb->event_mask)
414+
{
415+
k_sem_give(&wait->sem);
416+
}
417+
}
418+
419+
static void wait_for_net_event(struct net_if *iface, uint32_t event)
420+
{
421+
struct wait_data wait;
422+
423+
wait.cb.handler = event_cb_handler;
424+
wait.cb.event_mask = event;
425+
426+
k_sem_init(&wait.sem, 0, 1);
427+
net_mgmt_add_event_callback(&wait.cb);
428+
429+
k_sem_take(&wait.sem, K_FOREVER);
430+
431+
net_mgmt_del_event_callback(&wait.cb);
432+
}
433+
401434
/** Gets the local IP address and local broadcast address from the system,
402435
* and saves it into the BACnet/IP data structures.
403436
*
@@ -406,6 +439,7 @@ int bip_send_pdu(BACNET_ADDRESS *dest,
406439
*/
407440
void bip_set_interface(const char *ifname)
408441
{
442+
char hr_addr[NET_IPV4_ADDR_LEN];
409443
struct net_if *iface = 0;
410444
int index = -1;
411445
uint8_t x = 0;
@@ -434,15 +468,46 @@ void bip_set_interface(const char *ifname)
434468
}
435469
}
436470
if (index == -1) {
437-
LOG_WRN("%s:%d - No valid interface specified - using default ",
471+
LOG_INF("%s:%d - No valid interface specified - using default ",
438472
THIS_FILE, __LINE__);
439473
iface = net_if_get_default();
440474
}
441475
if (iface) {
442476
LOG_INF("Interface set.");
477+
if (!net_if_is_up(iface))
478+
{
479+
LOG_INF("Bringing up network interface");
480+
int ret = net_if_up(iface);
481+
if ((ret < 0) && (ret != -EALREADY))
482+
{
483+
LOG_ERR("Failed to bring up network interface: %d", ret);
484+
return;
485+
}
486+
}
487+
if (BIP_Address.s_addr != 0)
488+
{
489+
net_if_ipv4_addr_add(iface, &BIP_Address, NET_ADDR_MANUAL, 0);
490+
LOG_INF("static IPv4 address: %s",
491+
net_addr_ntop(AF_INET, &BIP_Address, hr_addr,
492+
NET_IPV4_ADDR_LEN));
493+
494+
net_if_ipv4_set_netmask_by_addr(iface, &BIP_Address, &BIP_Broadcast_Addr);
495+
LOG_INF("static IPv4 netmask: %s",
496+
net_addr_ntop(AF_INET, &BIP_Broadcast_Addr, hr_addr,
497+
NET_IPV4_ADDR_LEN));
498+
return;
499+
}
500+
#if defined(CONFIG_NET_DHCPV4)
501+
LOG_INF("Starting DHCP to obtain IP address");
502+
net_dhcpv4_start(iface);
503+
#endif
504+
505+
LOG_INF("Waiting to obtain IP address");
506+
wait_for_net_event(iface, NET_EVENT_IPV4_ADDR_ADD);
507+
443508
#if defined(CONFIG_BACDL_BIP_ADDRESS_INDEX)
444509
LOG_INF("Config unicast address %d/%d",
445-
CONFIG_BACDL_BIP_ADDRESS_INDEX, NET_IF_MAX_IPV4_ADDR);
510+
CONFIG_BACDL_BIP_ADDRESS_INDEX, NET_IF_MAX_IPV4_ADDR-1);
446511
index = CONFIG_BACDL_BIP_ADDRESS_INDEX;
447512
#else
448513
int i;
@@ -454,6 +519,11 @@ void bip_set_interface(const char *ifname)
454519
if (!if_addr->is_used) {
455520
continue;
456521
}
522+
#if defined(CONFIG_NET_DHCPV4)
523+
if (if_addr->addr_type != NET_ADDR_DHCP) {
524+
continue;
525+
}
526+
#endif
457527
index = i;
458528
LOG_INF("IPv4 address: %s",
459529
net_addr_ntop(AF_INET, &if_addr->address.in_addr, hr_addr,

0 commit comments

Comments
 (0)