Oprogramowanie Android odbieranie statusu ze sterowników inteligentnego domu po UDP

Sterowniki Ethernet Inteligentny Dom eHouse umożliwiają automatyczne wysyłanie statusu w formie broadcastu UDP (User Datagram Protocol), które mogą odbierać wszystkie urządzenia znajdujące się w lokalnej sieci LAN lub WiFi i spełniające warunek adresu IP – znajdowania się w lokalnej masce 255.255.255.0 co oznacza rozgłaszanie statusu sterowników na adresy IP 192.168.0.x.
Broadcast UDP pozwala na wyłączenie pobierania statusu przez klienta TCP/IP, który wymaga połączenia się do sterownika. Broadcast UDP jest protokółem bezpołączeniowym, rozgłoszeniowym i bez względu na ilość odbierających urządzeń nie obciąża to bardziej procesora ani łącza.

Prosta funkcja odbioru broadcastu UDP ze smartphonów, paneli i tabletów Android jest przedstawiona poniżej.
Jest to pętla nieskończona więc w oparciu o tą funkcję trzeba utworzyć wątek (THREAD) pracujący w tle, nadając mu jak najmniejszy priorytet pracy.
W przeciwnym razie wykonanie tej funkcji zablokuje wykonanie innych działań programu.

Kod źródłowy odbioru Broadcastu UDP dla platformy android:

 

public void udp(int port)  //parametr port na którym odbieramy broadcast domyślnie 6789 – status sterownika w formacie binarnym
{

byte[] broadcastadr = new byte[4];
byte[] localadr=new byte[4];
WifiManager    wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);  //wifi manager
DhcpInfo  dhcp = wifi.getDhcpInfo();   //get dhcp info from wifi
if (dhcp == null) //get default value if dhcp is disabled network of eHouse
{   //brak dhcp lub błąd dla urządzenia
broadcastadr[0]=(byte)192;
broadcastadr[1]=(byte)168;
broadcastadr[2]=(byte)0;
broadcastadr[3]=(byte)255;
}
else  //DHCP
{
int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;    // for udp broadcast – w przypadku chęci rozgłaszania danych dalej funkcja ta tylko odbiera statusy sterowników
for (int k = 0; k < 4; k++)      broadcastadr[k] = (byte) ((broadcast >> k * 8) & 0xFF);
int local = (dhcp.ipAddress );    //lokalny adres ip z dhcp
for (int k = 0; k < 4; k++)      localadr[k] = (byte) ((local >> k * 8) & 0xFF); //for local ip address
}
try
{
ds=new DatagramSocket(port);///listening udp data on port from any ip
inside a mask – tworzenie instancji socketu udp nr portu lokalnego
}
catch (Exception e)
{
//              ehousecommunication.l(“Error Inet: get address”+e.getMessage()); for test
}
try
{
ds.setBroadcast(true);     //enable send broadcast message – dla transmisji
ds.setReuseAddress(true);  //enable multiple socket use the same IP address
//ds.setSoTimeout(400);    //reception timeout

}
catch (Exception io)
{  //ignorujemy błędy ale zabezpieczamy się przed błędami aplikacji i systemu

}

//* Udp broadcast TEST – testowe nadawanie broadcastu udp z telefonu lub tabletu – przyszłe zastosowania komunikacji z systemem
/*try
{
DatagramPacket dd=new DatagramPacket(“Hello UPD Word from Android TEST”.getBytes(),0,”Hello UPD Word from Android TEST”.length(),
InetAddress.getByAddress(broadcastadr),port);
ds.send(dd);  //wysyła DatagramPacket
}
catch (Exception e)
{
ehousecommunication.l(“Error Transmit Datagram packet: “+e.getMessage());

}
*/

MulticastLock ml = wifi.createMulticastLock(“Multicast lock enabled”);
//tworzy instancję blokady multicastu i broadcastu
ml.acquire(); //Multicast lock enable udp broadcast reception – can be disabled on certain android smartphones for batery saving purposes – włącza obsługę broadcastu UDP w telefonie jeśli nie jest zablokowane a tylko wyłączone

while (!ehousecommunication.Terminate)   //infinite loop for udp reception
{    //nieskończona pętla odbioru statusu udp
DatagramPacket dp=new DatagramPacket(message,message.length);        //create udp datagram packet using data buffer – tworzy udp pakiet z wykorzystaniem bufora “message”
try{
ds.receive(dp);      //udp packet reception from ehouse system – odbiera pakiet udp z danego portu soketa UDP
if (dp.getLength()>0) // jeśli rozmiar paczki większy od zera – coś odebrał
{
EhouseTCP.QueryBuff=dp.getData(); //assign udp broadcast recepition to querybuffer – ładuje do bufora statusu eHouse
//dp.setLength(0); – ustawia wielkość pakietu na zero żeby nie przetwarzał wielokrotnie tych samych danych
EhouseTCP.QueryReceived();    //decode query data and fill devices arrays -dekoduje dany status sterowników i ładuje do tabeli statusu aplikacji
}
}
catch (Exception os)
{ // ignoruje błędy
//        ehousecommunication.l(“asdfasdfsafsa”+os.getMessage())  ;   //for test only
}

}
ml.release(); // multicast lock free for udp reception of eHouse application – uwalnia multicast lock
ds.close();   //close datagram socket at the end – zamyka socket na koniec
}

Multicast lock może być wymagany w niektórych urządzeniach Android.

Lokalny Broadcast UDP w przypadku telefonów komórkowych może być aktywny lub nie w zależności od firmwaru telefonu komórkowego.
Może być także permanentnie zablokowany w celach oszczędności baterii i z powodów bezpieczeństwa lub zmniejszenia obciążenia procesora przy pracy w sieci.
(należy zwrócić uwagę na konfigurację kernela: CONFIG_IP_MULTICAST is not set).
Dodatkowo w niektórych modelach może być blokowany przez lokalny FireWall i trzeba uaktywnić transmisję na danym porcie (domyślnie 6789).
Zewnętrzny Broadcast przy używaniu łączy internetowych GPRS, EDGE, 3G, 4G może być zablokowany lub odblokowany przez operatora sieci. Częściej należy się jednak liczyć, że jest on zablokowany w celu minimalizacji utylizacji łącza.
W niektórych modelach telefonów komórkowych, realizacja oprogramowania odbierającego statusy sterowników UDP może być bardzo utrudniona lub wręcz niemożliwa. Może wymagać użycia niebrandowanego lub specjalnego firmwaru smartphonu.
Dodatkowo należy uważać przy upgradowaniu firmwaru i sprawdzić czy wszystkie funkcje aplikacji pracują prawidłowo od razu po instalacji, gdyż w innym przypadku zdiagnozowanie powodu błędów będzie bardzo trudne.
Na podstawie kilku modeli telefonów HTC i innych zawierających system operacyjny Android w wersji niższej niż 2.3.3 zaobserwowano całkowitą blokadę odbioru broadcastu UDP. Dotyczyło to wersji android (2.1 – 2.3 z okresu 01.01.2010 – 14.06.2011)

W przypadku braku możliwości odbioru broadcastu UDP należy pobrać i zainstalować, nowy ROM Androida w minimalnej wersji 2.3.3 (z 14 czerwca 2011), na której przetestowano poprawność pracy odbiorów broadcastów UDP.
Wersja jądra 2.6.35.10-g3ef43272 htc-kernel@and18-2 #1.
Numer oprogramowania 3.14.405.1.
Dla innych marek telefonów w przypadku podobnych problemów należy pobierać Rom Firmwaru Androida ze strony producenta w wersji co najmniej 2.3.3.

Należy pamiętać także o podstawowych cechach Pakietów UDP.
Są one asynchroniczne i wymagają odczytania na bieżąco co może powodować błędy odczytu danych, ich utratę (gubienie) szczególnie przy wolnych urządzeniach, łączach, dużym obciążeniu łącz oraz zajęciu procesora SmartPhonów i tabletów.
Dane statusu udp są wysyłane podwójnie więc należy porównać czy wszystkie bajty obu kopi są takie same, a jeśli nie to po prostu je zignorować.

inteligentny Budynek eHouse
Automatyka Domu, Automatyka Domowa eHouse
sterowniki mikroprocesorowe eHouse

Więcej informacji o wykorzystaniu broadcastu UDP w sterownikach eHouse:
Inteligentny Dom eHouse – Dekodowanie broadcastu UDP z CommManagera dla PC – Windows XP, Vista, 7 w Delphi
Inteligentny Dom – odbiór i dekodowanie statusu binarnego ze sterowników kod źródłowy
inteligentny dom – dekodowanie statusu binarnego ze sterowników kod źródłowy
inteligentny dom – współpraca paneli sterujących ze sterownikami po UDP
Inteligentny Dom – komunikacja UDP pomiędzy sterownikami mikroprocesorowymi a oprogramowaniem PC