Reading value from Real BACnet Device on using BAC0 - networking

I was trying to use BAC0 package in python 3 to get value from BACnet device available in BACnet network.
import BAC0
bacnet = BAC0.lite(ip='192.168.5.10/24' ,port=47809)
value = bacnet.read("192.168.5.13:47808 analogInput 1 presentValue")
Where 192.168.5.10 is my local PC Host address and 192.168.5.13 is the ip address of BACnet Device
Getting error :
BAC0.core.io.IOExceptions.NoResponseFromController: APDU Abort Reason : Timeout

First off - for the benefit of others, you're missing a new-line after the 'import BAC0' statement.
I've just tested with a slight variant (- not that I'm a Python developer), but it seemed to work; I've masked the exact IP addresses that I tested with):
import BAC0
BAC0.log_level('info')
bacnet = BAC0.lite(ip = '192.168.n.h/24', port = 47809)
value = bacnet.read("195.n.n.h:47808 analogInput 1 presentValue")
print(value)
Are you sure you've got the correct (IP address and) port #?
Has the default gateway been set upon the 'server'/serving/target device (- at least in the case whereby the BACnet client & server are sitting within different subnets)?
Are you sure that this target/'server' device does not also have a DNET & DADR pair of values associated with it - i.e. also require them to be specified?
Is there a F/W blocking communication?
Is the device currently (marked as) 'out-of-service' (or encountering an issue)?
Has it got a valid BACnet license and/or BACnet configuration applied?
You might need to diagnose further with Wireshark, to see what response octets/bytes are been sent back (if any - and maybe even what 'service' request octets/bytes are been sent); or maybe even 'VTS' (Visual Test Shell) instead/too.

Related

Setting port for gRPC server

From my understanding, gRPC's protocol is http2 on top of TCP. Therefore, the maximum port that can be assigned is 65535, right? But it seems like if I set the server address to be something like "0.0.0.0:70040" which is out of the range, it is still working fine and the gRPC client is able to connect and communicate with the gRPC server. May I know what does this actually mean? Thank you.
builder.AddListeningPort("0.0.0.0:70040", grpc::InsecureServerCredentials());
I suspect the issue is that, the use of strings for the endpoint address limits the ability of the compiler to validate the unsigned 16-bit port address.
70040 by my early morning calculation is 10001000110011000 which is 17-bits. Ports must be 16-bits so one of these bits will be getting dropped, probably the most significant one (1).
Dropping that, yields 1000110011000 which corresponds to 4504 and it's likely the actual port that's being used.
You could try running the server on 70040 and connect to it from the the client using 4504.

What is the difference between a 'shallow' and 'deep' ping?

So as a fairly new (out-in-the-world-working) developer I'm not unfamiliar to the concept of pinging as it was taught to me in uni and I've used it in various small assignments I've encountered before.
My understanding of it is determining whether another host is present and responsive on a network.
I've implemented in Java (the language i'm most comfortable in) some code similar to the one below when wanting to achieve pinging:
try {
String ip = "127.192.199.01";
InetAddress inet = InetAddress.getByName(ip);
System.out.println("Send ping-request to: " + ip);
if (inet.isReachable(5000)){
System.out.println(ip + " is reachable.");
} else {
System.out.println(ip + " NOT reachable.");
}
} catch ( Exception e ) {
System.out.println("Exception:" + e.getMessage());
}
However I pretty new to the concept of 'shallow' and 'deep' pinging which is something I've encountered at my current workplace.
So far though I've been able to figure out that deep pinging is basically about testing that all connections are alive and working while testing functionality through as much of a webstack as possible.
Got that from: what is deep_ping
My question is:
What does a shallow ping do then?
And what is then the main difference (if any) between a shallow and deep ping?
Shallow ping works by sending one or more (ICMP/ICMP6) Echo Request packets to the host and only tests if the network is working i.e. if the host is reachable from your machine.
Deep pinging works by testing the application. How the deep ping is implemented is up to the developer but it could be via a "status" endpoint which responds with the current application status, or another similar interface (as described in the link you already mentioned).
As per your link, deep pinging can also mean testing an entire subnet or testing other protocols than the standard Echo Request.
This sounds like you are performing host availability test on different OSI layers (https://en.wikipedia.org/wiki/OSI_model)
A ping how you know it is performed on the transport layer, where a single packet is sent to the other machine and the OS responds with another packet.
In that case you do not know if there is ANY application running on that node other than the clean OS.
Going further up in the OSI layers you can then perform tests on you business logic like calling APIs of your HTTP based REST API
My gut feeling is that "shallow ping" means a ping performed using the standard ICMP request (the well known ping command we know about), a "deep ping" is trying to access the actual remote service by opening a socket on a given port and see if you get any answer
How I can interpret it:
Shallow ping : The host is available, port on which service is exposed is accepting. (more like telnet)
Deep ping : You are actually hitting one of the service and getting an expected response back.
Again, these are more like custom terms, not an actually defined standard.

asterisk error:chan_sip.c:4274 __sip_reliable_xmit: Serious Network Trouble; __sip_xmit returns error for pkt data

I got the above error when try to connect two soft phones which is successfully registered. I was trying to make a voice call in local not connecting and instead returns the error:
chan_sip.c:4274 __sip_reliable_xmit: Serious Network Trouble; __sip_xmit returns error for pkt data
I am using asterisk 13.5.0 and not using freepbx. Simply try to make a call between two peers
Make changes to sip.conf edit the line bind address like bindaddr=0.0.0.0
Likly firewall or permissions(for socket) issues.
Solved
OK I've just solved this issue in my network.
First of all , about the situation : i had an "Issabel VoIP server" based on Asterisk 13 but when i wanted to make calls ,it just failed and i got the same error as yours on Asterisk CLI. I had successful ping requests from the server and extension had been registered without any errors.
Solution: I had doubt about network devices, so i installed 2 soft-phones (like 3cx or Zoiper) on my laptop and connected it straightly to the server using a LAN patch cord ( to see if there's an issue on server side or its related to my network infra.) and registered 2 extensions on my soft-phone and they called each other without problem.so i understood that its one of my network devices that was limiting the transition of VoIP packets between server and extensions . finally i got that it was my TDD-LTE Modem that intercept my connection.
So to make long story short :
1- First create a small network between your server and laptop
2- Register 2 extensions on your soft-phone
3- make call between them and if it goes fine , then look for an obstacle in your main network.
hope it could help you

Creating an HTTP server in NodeMCU through an access point created by the board

I am coding a robot, using NodeMCU (ESP8266) and want it to be remote controlled. My current solution is connecting to a nearby router, to the internet and creating a TCP HTTP server. Data is streamed from the mobile device (remote) to the NodeMCU (robot) via HTTP requests. The remote is loaded onto the mobile device through a browser with HTML/CSS/JavaScript.
What I want instead is for the NodeMCU to create its own hotspot, because:
A router is not required
The connection is more direct
I want the same TCP HTTP solution, but I don't know how to serve a webpage through a custom hotspot.
This is my code:
-- Connect to router
wifi.sta.config("ssid","password")
wifi.sta.connect()
-- Code for waiting for connection
-- Create server
srv = net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:on("receive",function(conn,payload)
for line in string.gmatch(payload,'[^\r\n]+') do
s = string.find(line, "GET /&")
-- If query is there, control robot
if s ~= nil then
-- Do stuff with query
break;
-- If no query, serve webpage
else
file.open("index.html", "r")
while true do
s = file.read(1460)
if s == nil then
break
end
conn:send(s)
end
file.close()
end
break
end
conn:on("sent", function(conn) conn:close() end)
end)
end)
Creating custom hotspot:
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="custom_ssid"
cfg.pwd="custom_password"
wifi.ap.config(cfg)
So how do I make it so the mobile can access the server? How do I get/set the IP of the server? Basically, I just need it to work. Thanks!
Not sure I fully understand but I believe you're really close. Check the documentation for the AP functions at http://nodemcu.readthedocs.io/en/latest/en/modules/wifi/#wifiap-module.
wifi.ap.config(cfg) sets SSID and pwd as you noted. Your client then connects to this AP by joining the network.
If you then print wifi.ap.getip() you'll see that the device has the IP address 192.168.1.4 by default. Hence, for clients which joined this network your server is reachable at 192.168.1.4:80 unless you set a custom IP explicitly.
However, the sending of data seems broken. You have multiple conn:send(s) (in the loop) yet you also have conn:on("sent", function(conn) conn:close() end) which means that the connection will be closed after the first conn:send! Check the docs at http://nodemcu.readthedocs.io/en/latest/en/modules/net/#netsocketsend for an example as for how to do that properly.

Determining when to try an IPv6 connection and when to use IPv4

I'm working on a network client program that connects to public servers, specified by the user. If the user gives me a hostname to connect to that has both IPv4 and IPv6 addresses (commonly, a DNS name with both A and AAAA records), I'm not sure how I should decide which address I should connect to.
The problem is that it's quite common for machines to support both IPv4 and IPv6, but only to have global connectivity over IPv4. The most common case of this is when only IPv6 link-local addresses are configured. At the moment the best alternatives I can come up with are:
Try the IPv6 address(es) first - if the connection fails, try the IPv4 address(es); or
Just let the user specify it as a config setting ("prefer_ipv6" versus "prefer_ipv4").
The problem I can see with option 1 is that the connection might not fail straight away - it might take quite a while to time out.
Please do try IPv6. In the significant majority of installations, trying to create an IPv6 connection will fail right away if it can't succeed for some reason:
if the system doesn't support IPv6 sockets, creating the socket will fail
if the system does support IPv6, and has link-local addresses configured, there won't be any routing table entry for the global IPv6 addresses. Again, the local kernel will report failure without sending any packets.
if the system does have a global IP address, but some link necessary for routing is missing, the source should be getting an ICMPv6 error message, indicating that the destination cannot be reached; likewise if the destination has an IPv6 address, but the service isn't listening on it.
There are of course cases where things can break, e.g. if a global (or tunnel) address is configured, and something falsely filters out ICMPv6 error messages. You shouldn't worry about this case - it may be just as well that IPv4 connectivity is somehow broken.
Of course, it's debatable whether you really need to try the IPv6 addresses first - you might just as well try them second. In general, you should try addresses in the order in which they are returned from getaddrinfo. Today, systems support configuration options that let administators decide in what order addresses should be returned from getaddrinfo.
Subsequent to the question being asked the IETF has proposed an answer to this question with RFC6555, a.k.a. Happy Eyeballs.
The pertinent point being the client and server may both have IPv4 and IPv6 but a hop in between may not so it is impossible to reliably predict which path will work.
You should let the system-wide configuration decide thanks to getaddrinfo(). Just like Java does. Asking every single application to try to cater for every single possible IPv6 (mis)configuration is really not scalable! In case of a misconfiguration it is much more intuitive to the user if all or none applications break.
On the other hand you want to try to log annoying delays and time-outs profusely, so users can quickly identify what to blame. Just like every other delays ideally, including (very common) DNS time-outs.
This talk has the solution. To summarize;
Sometimes there are problems with either DNS lookups or the subsequent connection to the resolved address
You don't want to wait for connecting to an IPv6 address to timeout before connecting to the IPv4 address, or vice versa
You don't want to wait for a lookup for an AAAA record to timeout before looking for an A record or vice versa
You don't want to stall while waiting for both AAAA and A records before attempting to connect with whichever record you get back first.
The solution is to lookup AAAA and A records simultaneously and independently, and to connect independently to the resolved addresses. Use whatever connection succeeds first.
The easiest way to do this is to allow the networking API do it for you using connect-by-name networking APIs. For example, in Java:
InetSocketAddress socketAddress = new InetSocketAddress("www.example.com", 80);
SocketChannel channel = SocketChannel.open(socketAddress);
channel.write(buffer);
The slide notes say at this point:
Here we make an opaque object called an InetSocketAddress from a host
and port, and then when we open that SocketChannel, that can complete
under the covers, doing whatever is necessary, without the
application ever seeing an IP address.
Windows also has connect-by-name APIs. I don’t have code fragments for
those here.
Now, I’m not saying that all implementations of these APIs necessarily
do the right thing today, but if applications are using these APIs,
then the implementations can be improved over time.
The di!erence with getaddrinfo() and similar APIs is that they
fundamentally can’t be improved over time. The API definition is that
they return you a full list of addresses, so they have to wait until
they have that full list to give you. There’s no way getaddrinfo can
return you a partial list and then later give you some more.
Some ideas:
Allow the user to specify the preference on a per-site basis.
Try IPv4 first.
Attempt IPv6 in parallel upon the first connection.
On subsequent connections, use IPv6 if the connection was successful previously.
I say to try IPv4 first because that is the protocol which is better established and tested.

Resources