Change PAN ID and disassociation packet in ZigBee - xbee

I tried to change ZigBee's PAN ID and node discovery, but as soon as I changed its PAN ID, I received a modem status packet (0x03) that apparently described disassociation. After that, I send ATND command for node discovery, and I got modem status (0x06) -- coordinator start, but no discovery result.
I found that if I send any ATND command again after first ATND command, it worked as I expected. Why was a disassociation packet received from ZigBee after I changed the PAN ID?

When you change the PAN ID on a coordinator, it's shutting down one network (disassociation) and then creating another (coordinator started). You then need to wait for nodes to join that new network before you can discover them. It doesn't make sense to perform node discovery on a device that isn't currently joined to a network.
If you set ATJN to 1 on the coordinator, the host will receive Join Notification frames (type 0xA5) as devices join the network. Maybe this is what you're looking for?

Related

What is the meaning of 'sender=:1.478' in dbus-monitor?

Nowadays I am analyzing d-bus in Chromium OS (Chrome OS).
I captured meaningful d-bus method calls (below), when I press ''guest' button on login UI.
my-cros # dbus-monitor --system "path=/org/chromium/Session Manager"
method call time=1632311881.319994 sender=: 1.478 -> destination=org.chromium. SessionManager serial=378 path=/org/chromium/Session Manager; interface=org.chromium.SessionManager Interface: member=LoadShil1Profile
string "$guest"
method call time=1632311881.319417 sender:1.478 -> destination=org. chromium. Session Manager serial=371 path=/org/chromium/SessionManager; interface=org.chromium.SessionManager Interface: member-SetFeatureFlagsFor User string "$guest"
array [
]
array [
]
I know that org.chromium.SessionManager is the one who starts guest/google-id session.
Btw what is the meaning of 'sender=:1.478'?
And how to track the sender process?
Thank you in advance.
Firstly, you might find it easier to visualise what’s going on by using Bustle instead of dbus-monitor.
sender=:1.478 means the message you’re looking at was sent by the connection with unique ID :1.478 on the bus. Each connection to the bus (roughly, each process, although a process can actually have more than one connection) has a unique ID, and some connections also have ‘well-known’ IDs which look like reverse-DNS names. For example org.chromium.SessionManager.
You can track the sender process by looking for the same unique ID appearing as the sender or destination of other messages. Using Bustle will make this easier, as it can group and filter messages by sender/destination.

get_multiple_points volttron RPC call

Any chance I could get a tip for proper way to build an agent that could do read multiple points from multiple devices on a BACnet system? I am viewing the actuator agent code trying learn how to make the proper rpc call.
So going through the agent development procedure with the agent creation wizard.
In the init I have this just hard coded at the moment:
def __init__(self, **kwargs):
super(Setteroccvav, self).__init__(**kwargs)
_log.debug("vip_identity: " + self.core.identity)
self.default_config = {}
self.agent_id = "dr_event_setpoint_adj_agent"
self.topic = "slipstream_internal/slipstream_hq/"
self.jci_zonetemp_string = "/ZN-T"
So the BACnet system in the building has JCI VAV boxes all with the same zone temperature sensor point self.jci_zonetemp_string and self.topic is how I pulled them into volttron/config store through BACnet discovery processes.
In my actuate point function (copied from CSV driver example) am I at all close for how to make the rpc call named reads using the get_multiple_points? Hoping to scrape the zone temperature sensor readings on BACnet device ID's 6,7,8,9,10 which are all the same VAV box controller with the same points/BAS program running.
def actuate_point(self):
"""
Request that the Actuator set a point on the CSV device
"""
# Create a start and end timestep to serve as the times we reserve to communicate with the CSV Device
_now = get_aware_utc_now()
str_now = format_timestamp(_now)
_end = _now + td(seconds=10)
str_end = format_timestamp(_end)
# Wrap the timestamps and device topic (used by the Actuator to identify the device) into an actuator request
schedule_request = [[self.ahu_topic, str_now, str_end]]
# Use a remote procedure call to ask the actuator to schedule us some time on the device
result = self.vip.rpc.call(
'platform.actuator', 'request_new_schedule', self.agent_id, 'my_test', 'HIGH', schedule_request).get(
timeout=4)
_log.info(f'*** [INFO] *** - SCHEDULED TIME ON ACTUATOR From "actuate_point" method sucess')
reads = publish_agent.vip.rpc.call(
'platform.actuator',
'get_multiple_points',
self.agent_id,
[(('self.topic'+'6', self.jci_zonetemp_string)),
(('self.topic'+'7', self.jci_zonetemp_string)),
(('self.topic'+'8', self.jci_zonetemp_string)),
(('self.topic'+'9', self.jci_zonetemp_string)),
(('self.topic'+'10', self.jci_zonetemp_string))]).get(timeout=10)
Any tips before I break something on the live system greatly appreciated :)
The basic form of an RPC call to the actuator is as follows:
# use the agent's VIP connection to make an RPC call to the actuator agent
result = self.vip.rpc.call('platform.actuator', <RPC exported function>, <args>).get(timeout=<seconds>)
Because we're working with devices, we need to know which devices we're interested in, and what their topics are. We also need to know which points on the devices that we're interested in.
device_map = {
'device1': '201201',
'device2': '201202',
'device3': '201203',
'device4': '201204',
}
building_topic = 'campus/building'
all_device_points = ['point1', 'point2', 'point3']
Getting points with the actuator requires a list of point topics, or device/point topic pairs.
# we only need one of the following:
point topics = []
for device in device_map.values():
for point in all_device_points:
point_topics.append('/'.join([building_topic, device, point]))
device_point_pairs = []
for device in device_map.values():
for point in all_device_points:
device_point_pairs.append(('/'.join([building_topic, device]),point,))
Now we send our RPC request to the actuator:
# can use instead device_point_pairs
point_results = self.vip.rpc.call('platform.actuator', 'get_multiple_points', point_topics).get(timeout=3)
maybe it's just my interpretation of your question, but it seems a little open-ended - so I shall respond in a similar vein - general (& I'll try to keep it short).
First, you need the list of info for targeting each device in-turn; i.e. it might consist of just a IP(v4) address (for the physical device) & the (logical) device's BOIN (BACnet Object Instance Number) - or if the request is been routed/forwarded on by/via a BACnet router/BACnet gateway then maybe also the DNET # & the DADR too.
Then you probably want - for each device/one at a time, to retrieve the first/0-element value of the device's Object-List property - in order to get the number of objects it contains, to allow you to know how many objects are available (including the logical device/device-type object) - that you need to retrieve from it/iterate over; NOTE: in the real world, as much as it's common for the device-type object to be the first one in the list, there's no guarantee it will always be the case.
As much as the BACnet standard started allowing for the retrieval of the Property-List (property) from each & every object, most equipment don't as-yet support it, so you might need your own idea of what properties (/at least the ones of interest to you) that each different object-type supports; probably at the very-very least know which ones/object-types support the Present-Value property & which ones don't.
One ideal would be to have the following mocked facets - as fakes for testing purposes instead of testing against a live/important device (- or at least consider testing against a noddy BACnet enabled Raspberry PI or the harware-based like):
a mock for your BACnet service
a mock for the BACnet communication stack
a mock for your device as a whole (- if you can't write your own one, then maybe even start with the YABE 'Room Control Simulator' as a starting point)
Hope this helps (in some way).

How can I update sofia when the current Ip address changes?

I have developed a small voip client application in C using sofia library and based on the sofia-sip client example.
Evertyhing works fine but one thing, if my Ip address changes once the application is running sofia doesn't update itself. I'll explain myself:
When I execute my voip application (running in Linux) sofia takes the current Ip address and the application will accept all the incoming calls to that address.
If the IP of the device where the application is running is changed (updating network config of Linux) i'm not able to update sofia in order to work with the new ip, therefore any incoming call is not received.
I've tried with ssc_set_public_address, which updates ssc_address and set the new value in nua using nua_set_params:
/**
* Sets the public address used for invites, messages,
* registrations, etc method.
*/
void ssc_set_public_address(ssc_t *ssc, const char *address)
{
if (address) {
su_free(ssc->ssc_home, ssc->ssc_address);
ssc->ssc_address = su_strdup(ssc->ssc_home, address);
nua_set_params(ssc->ssc_nua,
SIPTAG_FROM_STR(ssc->ssc_address),
TAG_NULL());
}
}
After doing it, it looks like the internal ip address has changed (if I read it using get_params I get the new one), however something is missed because no incoming call will be received.
In order to work with the new IP I need to reboot the whole application.
Does anybody know how to really update the sofia IP without rebooting the application?
Thank you.

Xbee simple communication using Python?

As a part of my project I am using XBee. I want sample Python code to make two XBees to communicate with each other in Windows. I have written code, but it has a problem.
What would like to sent a message like "hello" from one XBee, and it should be printed on the other XBee side. How can I do this?
Take a look at the great python-xbee library, and Digi's examples.digi.com as two excellent resources for someone new to the XBee. Between those two sites, you should be able to get your XBee radios joined to each other (using the second link) and then get them working in Python (with the first link).
Before doing anything else you have to configure the devices, use XCTU software:
First device - Coordinator API mode:
- ID 7777(or any random value)
- DL set to FFFF
Second device - Router AT mode:
- ID 7777(has to be the same for every device)
- DL set to 0
Code for coordinator (listen mode):
import serial
import time
from xbee import ZigBee
PORT = "COM1" #change the port if you are not using Windows to whatever port you are using
BAUD_RATE = 9600
ser = serial.Serial(PORT, BAUD_RATE)
# Create API object
xbee = ZigBee(ser)
# Continuously read and print packets
while True:
try:
response = xbee.wait_read_frame()
print("\nPacket received at %s : %s" %(time.time(), response))
except KeyboardInterrupt:
ser.close()
break
Code for the remote device:
import serial
PORT = "COM1" #change the port if you are not using Windows to whatever port you are using
BAUD_RATE = 9600
ser = serial.Serial(PORT, BAUD_RATE)
while True:
try:
data = raw_input("Send:")
ser.write(data) #if you are using python 3 replace data with data.encode()
except KeyboardInterrupt:
ser.close()
break
Run the code and send data from the remote device to the coordinator. You will be able to see the packets printed in the console and in the rx_data field will be the payload.
I hope this is helpful.

Refresh multicast group membership

I have several embedded machines listening and streaming rtp audio data to a multicast group. They are connected to a smart managed switch (Netgear GS108Ev2) which does basic igmp snooping and multicast filtering on its ports, so that the rest of my (W)LAN doesn't get flooded.
At start everything works fine for about 500-520 seconds. After that, they don't receive any more data until they leave and join the group again. I guess the switch is "forgetting" about the join after a timeout.
Is there any way to refresh the group membership, i.e. letting the switch know, that there ist still someone listening, without losing packets?
System info:
Arch: blackfin
# cat /proc/version
Linux version 2.6.28.10-ADI-2009R1-uCBF54x-EMM
(gcc version 4.3.3 (ADI) ) #158 PREEMPT Tue Jun 5 20:05:42 CEST 2012
This is the way multicast / the IGMP protocol works. A client has to join the group periodically by sending a Membership Report or it will be assumed that he has left the group after some short timeout. However, those reports are usually sent only when receiving a Membership Query from the local multicast router. Either your clients don't receive the query or don't respond with a report.
Try to use a tool like wireshark in order to see which IGMP packets are sent through your network.
You need an IGMP querier to send the Membership Queries, as was already explained by scai.
If you can't configure your router to do that, you can use one of your computers. Seeing how running a full multicast routing daemon would be overkill (and I've never done that), I suggest you try to abuse igmpproxy.
First create a dummy upstream interface (this is not persistent!):
ip tap add dev tap6 mode tap
Write igmpproxy.conf:
# Dummy upstream interface.
phyint tap6 upstream ratelimit 0 threshold 1
# Local interface.
phyint eth0 downstream ratelimit 0 threshold 1
# Explicitly disable any other interfaces (yes, it sucks).
phyint NAME disabled
...
Finally start igmpproxy (as root):
igmpproxy -v /path/to/igmpproxy.conf
If your embedded devices are running linux, you need to turn off the reverse packet filter on them or they won't respond to group membership queries. In that case the upstream switch will assume there is no-one listening to that multicast and switch it off.
I had same problem, multicast on wifi was lost after 260 seconds, I solved it with my application by adding AddSourceMembership on socket.
private void StartListner(IPAddress sourceIp, IPAddress multicastGroupIp, IPAddress localIp, int port)
{
try
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint localEndpoint = new IPEndPoint(localIp, port);
socket.Bind(localEndpoint);
byte[] membershipAddresses = new byte[12]; // 3 IPs * 4 bytes (IPv4)
Buffer.BlockCopy(multicastGroupIp.GetAddressBytes(), 0, membershipAddresses, 0, 4);
Buffer.BlockCopy(sourceIp.GetAddressBytes(), 0, membershipAddresses, 4, 4);
Buffer.BlockCopy(localIp.GetAddressBytes(), 0, membershipAddresses, 8, 4);
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddSourceMembership, membershipAddresses);
try
{
byte[] b = new byte[1024 * 2];
int length = socket.Receive(b);
}
catch { }
}
catch (Exception ex)
{
logger.Error("Exception: " + ex);
}
}

Resources