Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Oczyszczacz powietrza i stos sieciowy? Czas na test! Semihalf Barcamp 13/06/2018

103 Aufrufe

Veröffentlicht am

Podczas wykładu pomijamy jakość filtracji powietrza natomiast skupiamy się na metodach testowania protokołów sieciowych przy wykorzystaniu języka TTCN-3. Sprawdzamy jakie dane nasze domowe urządzenia wysyłają w świat oraz jak można przejąć nad nimi kontrolę.

Veröffentlicht in: Software
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Oczyszczacz powietrza i stos sieciowy? Czas na test! Semihalf Barcamp 13/06/2018

  1. 1. Wykorzystanie języka TTCN-3 do testu oczyszczacza powietrza Jacek Klimkowicz Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  2. 2. Protokół Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. Dane (zmienna długość) Suma MD5 lub token Znacznik czasowy ID urządzenia Separator Magic number (0x2131) Długość pakietu
  3. 3. Hello request Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. 0xffffffffffffffffffffffffffffffff 0xffffffff 0xffffffff 0xffffffff 0x2131 0x0020
  4. 4. Hello answer Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. 0x00000000 0x2131 0x0020 ID urządzenia Znacznik czasowy Token
  5. 5. Blok danych ● Format JSON ● Najczęstszy format: ○ Request { “method”: “<method_name>”, “params”: [<list_of_params>] || {<param_object>}, “id”: <id> } ○ Answer { “result”: [<list_of_values>] || <result_code>, “id”: <id> } Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  6. 6. Szyfrowanie ● Blok danych szyfrowany przez AES ● 128 bitowy klucz oraz wektor inicjujący uzyskiwane z tokena: ○ key := MD5(token) ○ iv := MD5(key + token) ● Padding: PKCS#7 (RFC 2315) ● Tryb pracy: Cipher Block Chaining – CBC Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  7. 7. TTCN-3 ● Testing and Test Control Notation Version 3 ● Wieloczęściowy standard ETSI: ES 201 873-xx ● Zastosowanie w telekomunikacji, automotive, finanse ● Zaprojektowany specjalnie do przeprowadzania testów ● Wiele obszarów zastosowań testu: ○ funkconalne ○ niezawodności ○ wydajności ○ regresji ○ obciążenia ○ integracyjne Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  8. 8. TTCN-3 - Język ● Proceduralny z elementami obiektowości ● Pod względem struktury i operatorów zbliżony do języka C ● Abstrakcyjne typy danych ● Wzorce i zaawansowane metody porównań i weryfikacji ● Obsługa zdarzeń ● Zarządzanie timerami ● Zarządzanie werdyktami ● Synchroniczna i asynchroniczna komunikacja ● Równloległość ● Konstrukcje specyficzne dla testowania: alt, interleave, default, altstep Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  9. 9. TTCN-3 - Język ● Może być zintegrowany z innymi “typ-wartość” systemami ● W pełni zharmonizowany z ASN.1 ● Mogą zostać użyte funkcje i stałe C/C++ Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  10. 10. TTCN-3 - Narzędzia ● Conformiq - Automated Test Design ● Devoteam GmbH - TTCN-3 Toolbox ● Elvior - TestCast ● PragmaDev Studio ● Spirent Communications - TTworkbench ● Broadbit Test Tool ● Elvior free online TTCN-3 verification service ● T3Tools: T3Q and T3D ● Titan TTCN-3 Toolset ● TRex- the TTCN-3 Refactoring and Metrics Tool Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  11. 11. Środowisko Testowe ● Repozytorium: https://github.com/Semihalf/miio ● Obraz dockera (dockerhub) semihalf/ttcn3-titan:6.4.pl0 ● Generacja Makefile docker run --rm -u $(id -u):$(id -g) -v </path/to/repo>:/git --entrypoint=makefilegen <image:tag> -Ggt <project.tpd> ● Kompilacja docker run --rm -u $(id -u):$(id -g) -v </path/to/repo>:/git --entrypoint=make <image:tag> -C bin ● Uruchamianie testów docker run --rm -v </path/to/repo>:/git --net=host <image:tag> bin/<ets> bin/<config> [module.testcase] Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  12. 12. Wykrywanie i konfiguracja urządzeń Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  13. 13. Wykrywanie urządzeń ● Reset urządzenia - tworzy otwartą się wi-fi ● Wysłanie zapytania mDNS ○ adres: 224.0.0.251, udp port 5353 ○ QRR: "_miio._udp.local", PTR, IN ● W odpowiedzi urządzenie zgodne z miio odpowiada adresem mac, adresem ip oraz numerem portu ● Wysłanie pakietu Hello na uzyskany wcześniej adres ● Urządzenie odpowiada swoim ID, znacznikiem czasu oraz tokenem Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  14. 14. Konfiguracja urządzeń ● Wywołanie API urządzenia: { “method”: “miIO.config_router”, “params”: { “ssid”: “<network>”, “passwd”: “<password>”, “uid”: uid }, “id”: id } ● Odpowiedź: {“result”: 0, “id”: id} ● Urządzenie wyłączy swoją sieć i podejmie próbę podłączenia się do sieci podanej powyżej Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  15. 15. Architektura Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. MTC Mi mDNS Dispatcher DNS_PCO Sync_PCO Mi_External_PCO Mi_Internal_PCO Sync_PCO Mi_Internal_PCO
  16. 16. Sygnalizacja Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. MTC Mi mDNS 2.DNS query 3.DNS answer 1.discover() 4.Device 10.hello req 11.hello ans 15.config_router cmd 16.config_router reply Dispatcher 5.create()6.init() 7.register 8.send_hello() 9.hello req 12b.hello ans 12a.receive_hello() 13.config_router() 17.config_router reply 14.config_router cmd
  17. 17. Implementacja - komponenty Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. type component MTC_CT { var Mi_CT_List vg_Mi_CT_List := {}; var boolean vg_continue := true; } type component DNS_CT { port DNS_PT DNS_PCO; var Device vg_device; } type component Dispatcher_CT { port Mi_Internal_PT Mi_Internal_PCO; port Mi_External_PT Mi_External_PCO; port Sync_PT Sync_PCO; var ASP_Mi vg_asp; var Mi_CT vg_mi_comp; var Mi_CT_List vg_routingTable; } type component Mi_CT { port Mi_Internal_PT Mi_Internal_PCO; port Sync_PT Sync_PCO; var integer vg_id := 1; var octetstring vg_key var octetstring vg_iv; var Device vg_device; var integer vg_stamp; var IntegerList2 vg_int_values; timer T; }
  18. 18. Implementacja - porty Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. signature register(OCT4 p_did); type port Sync_PT procedure { inout register; } with { extension "internal" } type port Mi_Internal_PT message { inout ASP_Mi; } with { extension "internal" }
  19. 19. Implementacja - porty Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. type port Mi_External_PT message { inout ASP_Mi; out ASP_LANL2_open_interface; in ASP_LANL2_open_result, ASP_LANL2_Error; } with { extension "user LANL2asp_PT out( ASP_Mi -> ASP_LANL2 : function(f_encode_ASP_Mi); ASP_LANL2_open_interface -> ASP_LANL2_open_interface : simple ) in( ASP_v2_LANL2 -> - : discard; ASP_v2_LANL2_Error -> - : discard; ASP_LANL2 -> ASP_Mi : function(f_decode_ASP_LANL2_ASP_Mi), - : discard; ASP_LANL2_open_result -> ASP_LANL2_open_result : simple; ASP_LANL2_Error -> ASP_LANL2_Error : simple )" }
  20. 20. Implementacja - porty Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. type port DNS_PT message { inout ASP_DNS; out ASP_LANL2_open_interface; in ASP_LANL2_open_result, ASP_LANL2_Error; } with { extension "user LANL2asp_PT out( ASP_DNS -> ASP_LANL2 : function(f_encode_ASP_DNS); ASP_LANL2_open_interface -> ASP_LANL2_open_interface : simple ) in( ASP_v2_LANL2 -> - : discard; ASP_v2_LANL2_Error -> - : discard; ASP_LANL2 -> ASP_DNS : function(f_decode_ASP_LANL2_DNS), - : discard; ASP_LANL2_open_result -> ASP_LANL2_open_result : simple; ASP_LANL2_Error -> ASP_LANL2_Error : simple )" }
  21. 21. Implementacja - Mi_Packet Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. type record Mi_Packet { OCT2 magic_number ('2131'O), LIN2 packet_length, OCT4 unknown, OCT4 did, LIN4_BO_LAST stamp, OCT16 cksum, octetstring data optional } with { variant (packet_length) "LENGTHTO (magic_number,packet_length,unknown,did,stamp,cksum,data)"; variant (packet_length) "BYTEORDER(last)"; variant "PRESENCE(magic_number='2131'O)"; encode "RAW"; } external function f_enc_Mi_Packet(in Mi_Packet par) return octetstring with { extension "prototype(convert) encode(RAW)" } external function f_dec_Mi_Packet(in octetstring par, out Mi_Packet packet) return integer with { extension "prototype(backtrack) decode(RAW) errorbehavior(ALL:IGNORE)" }
  22. 22. Implementacja - ASP_Mi Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. type record ASP_Mi { OCT6 src_mac_address optional, OCT6 dst_mac_address, IPv4_header ip_header, IPv4_extension_headers ip_ext_headers optional, integer udp_src_port, integer udp_dst_port, Mi_Packet mi_packet }
  23. 23. Implementacja - f_encode_ASP_Mi (1) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_encode_ASP_Mi( in ASP_Mi p_asp ) return ASP_LANL2 { // Encode Mi ASP into UDP packet var UDP_packet vl_UDP_packet; vl_UDP_packet.header.srcport := p_asp.udp_src_port; vl_UDP_packet.header.dstport := p_asp.udp_dst_port; vl_UDP_packet.header.len := 0; vl_UDP_packet.header.cksum := 0; vl_UDP_packet.payload := f_enc_Mi_Packet(p_asp.mi_packet); var octetstring vl_data := f_UDP_enc(vl_UDP_packet); var UDP_pseudo_header vl_udp_pseudo_header := { ipv4 := { srcaddr := p_asp.ip_header.srcaddr, dstaddr := p_asp.ip_header.dstaddr, zero := 0, proto := c_ip_proto_udp, plen := lengthof(vl_data) } }
  24. 24. Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. var OCT2 vl_cksum := f_UDP_checksum(f_UDP_pseudo_header_enc(vl_udp_pseudo_header) & vl_data); vl_data[6] := vl_cksum[0]; vl_data[7] := vl_cksum[1]; // Encode UDP packet into IPv4 packet var IPv4_packet vl_IPv4_packet; vl_IPv4_packet.header := p_asp.ip_header; vl_IPv4_packet.ext_headers := p_asp.ip_ext_headers; vl_IPv4_packet.payload := vl_data; // Encode IPv4 packet into LANL2 ASP vl_data := f_IPv4_enc_eth(vl_IPv4_packet); vl_cksum := f_IPv4_checksum(vl_data); vl_data[10] := vl_cksum[0]; vl_data[11] := vl_cksum[1]; var ASP_LANL2 vl_ASP_LANL2; vl_ASP_LANL2.eth_dst_addr := p_asp.dst_mac_address; vl_ASP_LANL2.eth_src_addr := p_asp.src_mac_address; vl_ASP_LANL2.type_field := c_eth_proto_ipv4; vl_ASP_LANL2.payload := vl_data; return vl_ASP_LANL2; } with { extension "prototype(convert)" } Implementacja - f_encode_ASP_Mi (2)
  25. 25. Implementacja - f_decode_ASP_Mi (1) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_decode_ASP_LANL2_DNS (in ASP_LANL2 p_asp, out ASP_DNS p_result) return integer { // Drop non IPv4 packets if(p_asp.type_field != c_eth_proto_ipv4) {return -1;} p_result.src_mac_address := p_asp.eth_src_addr; p_result.dst_mac_address := p_asp.eth_dst_addr; var IPv4_packet vl_IPv4_packet; if(f_IPv4_dec_backtrack(p_asp.payload, vl_IPv4_packet, false) != 1) {return -1;} // The IPv4 options at the end of the header are not supported if(isbound(vl_IPv4_packet.header.hlen) and vl_IPv4_packet.header.hlen > 5) {return -1;} var LIN2_BO_LAST vl_cksum := vl_IPv4_packet.header.cksum; vl_IPv4_packet.header.cksum := 0; if(not match(oct2int(f_IPv4_checksum(f_IPv4_enc_eth(vl_IPv4_packet))), vl_cksum)) { setverdict(fail, "Incorrect IPv4 checksum"); return -1; }
  26. 26. Implementacja - f_decode_ASP_Mi (2) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. p_result.ip_header := vl_IPv4_packet.header; p_result.ip_ext_headers := vl_IPv4_packet.ext_headers; if( vl_IPv4_packet.header.proto != c_ip_proto_udp ) { // Dropping non UDP packet return -1; } var UDP_packet vl_UDP_packet := f_UDP_dec(vl_IPv4_packet.payload); p_result.udp_src_port := vl_UDP_packet.header.srcport; p_result.udp_dst_port := vl_UDP_packet.header.dstport; p_result.pdu_dns := dec_PDU_DNS(vl_UDP_packet.payload); return 0; } with { extension "prototype(backtrack)" }
  27. 27. Implementacja - Testcase Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. testcase tc_init() runs on MTC_CT { var DNS_CT vl_mDNS := DNS_CT.create("mDNS"); var Device vl_device; vl_mDNS.start(f_discover()); vl_mDNS.done(Device:?) -> value vl_device; var Dispatcher_CT vl_disp := f_create_Dispatcher(); var Mi_CT vl_Mi := Mi_CT.create("Mi") alive; vl_Mi.start(f_init_Mi_CT(vl_disp,-,vl_device)); vl_Mi.done; vl_Mi.start(f_s_hello(vl_device.ip)); vl_Mi.done; vl_Mi.start(f_r_hello(true)); vl_Mi.done; vl_Mi.start(f_s_command(valueof(t_cmd_config_router), refers(f_check_success))); vl_Mi.done; }
  28. 28. Implementacja - f_discover (1) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_discover() runs on DNS_CT return Device { var QResourceRecord vl_QResourceRecord := { qName := "_miio._udp.local", qType := DNS_PTR, qClass := DNS_IN } var charstring vl_hostaddr := f_getIP(); template ASP_DNS t_asp_dns := { src_mac_address := omit, dst_mac_address := '01005e0000fb'O, ip_header := t_IPv4_header( p_proto := c_ip_proto_udp, p_srcaddr := f_IPv4_addr_enc(vl_hostaddr), p_dstaddr := f_IPv4_addr_enc("224.0.0.251") ), ip_ext_headers := omit, udp_src_port := 5353, udp_dst_port := 5353, pdu_dns := t_pdu_dns({vl_QResourceRecord}) }
  29. 29. Implementacja - f_discover (2) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. map(self:DNS_PCO, system:DNS_PCO); DNS_PCO.send(t_asp_dns); timer T; T.start(1.0); var ASP_DNS vl_asp_dns; alt { [] DNS_PCO.receive(ASP_DNS:?) -> value vl_asp_dns { T.stop; var ResourceRecords vl_answers := vl_asp_dns.pdu_dns.answers; for(var integer i := 0; i < vl_asp_dns.pdu_dns.header.anCount; i := i + 1) { select(vl_answers[i].rrType) { case (DNS_A) {vg_device.ip := f_IPv4_addr_dec(vl_answers[i].rData.a);} case (DNS_SRV) {vg_device.portnum := vl_answers[i].rData.srv.portnum;} case (DNS_TXT) {vg_device.mac := str2oct(regexp(vl_answers[i].rData.txt[0], "*mac=([0-9a-f]#(12))", 0));} } } vg_device.name := "discovery"; vg_device.did := int2oct(0,4); vg_device.token := int2oct(0,16); } [] T.timeout {setverdict(fail)} } unmap(self:DNS_PCO, system:DNS_PCO); return vg_device; }
  30. 30. Implementacja - Dispatcher Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_create_Dispatcher() runs on MTC_CT return Dispatcher_CT { var Dispatcher_CT vl_disp := Dispatcher_CT.create("Dispatcher"); map(vl_disp:Mi_External_PCO, system:Mi_External_PCO); vl_disp.start(f_run_Dispatcher()); return vl_disp; } function f_run_Dispatcher() runs on Dispatcher_CT { var OCT4 vl_did; alt { [] Sync_PCO.getcall(register:{?}) -> param (vl_did) sender vg_mi_comp { vg_routingTable[oct2int(vl_did)] := vg_mi_comp; Sync_PCO.reply(register:{-}); repeat; } [] Mi_Internal_PCO.receive(ASP_Mi:?) -> value vg_asp { Mi_External_PCO.send(vg_asp); repeat; } [] Mi_External_PCO.receive(ASP_Mi:?) -> value vg_asp { Mi_Internal_PCO.send(vg_asp) to vg_routingTable[oct2int(vg_asp.mi_packet.did)]; repeat; } } }
  31. 31. Implementacja - f_init_Mi_CT Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_init_Mi_CT(Dispatcher_CT p_disp, integer p_index := -1, template Device p_device := omit) runs on Mi_CT { if(ispresent(p_device)) { vg_device := valueof(p_device); } else if(p_index >= 0) { vg_device := tsp_devices[p_index]; } else { testcase.stop; } vg_key := f_calculateMD5_oct(vg_device.token); vg_iv := f_calculateMD5_oct(vg_key & vg_device.token); connect(self:Mi_Internal_PCO, p_disp:Mi_Internal_PCO); connect(self:Sync_PCO, p_disp:Sync_PCO); Sync_PCO.call(register:{vg_device.did}) { [] Sync_PCO.getreply(register:{-}); } disconnect(self:Sync_PCO, p_disp:Sync_PCO); }
  32. 32. Implementacja - f_s_hello (1) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_s_hello(charstring p_destaddr := "255.255.255.255") runs on Mi_CT { var charstring vl_hostaddr := f_getIP(); Mi_Internal_PCO.send(t_asp_mi('ffffffffffff'O, vl_hostaddr, p_destaddr, vg_device.portnum, t_helloPacket)); } template Mi_Packet t_helloPacket := { magic_number := c_magic_number, packet_length := 0, unknown := 'FFFFFFFF'O, did := 'FFFFFFFF'O, stamp := oct2int('FFFFFFFF'O), cksum := 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'O, data := omit }
  33. 33. Implementacja - f_s_hello (2) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. template ASP_Mi t_asp_mi( OCT6 p_mac, charstring p_srcaddr, charstring p_dstaddr, integer p_portnum, template Mi_Packet p_mi_packet) := { src_mac_address := omit, dst_mac_address := p_mac, ip_header := t_IPv4_header( p_proto := c_ip_proto_udp, p_srcaddr := f_IPv4_addr_enc(p_srcaddr), p_dstaddr := f_IPv4_addr_enc(p_dstaddr) ), ip_ext_headers := omit, udp_src_port := tsp_src_portnum, udp_dst_port := p_portnum, mi_packet := p_mi_packet }
  34. 34. Implementacja - f_r_hello Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_r_hello(boolean p_initial_hello := false) runs on Mi_CT return Device { vg_stamp := -1; T.start(1.0); var ASP_Mi vl_asp_mi; alt { [] Mi_Internal_PCO.receive(ASP_Mi:?) -> value vl_asp_mi { if(p_initial_hello) { vg_device.did := vl_asp_mi.mi_packet.did; vg_device.token := vl_asp_mi.mi_packet.cksum; log("DID: ", vg_device.did); log("Token:", vg_device.token); } else if(not match(vl_asp_mi.mi_packet.did, vg_device.did)) { repeat; } log("HELLO response: ", vl_asp_mi.mi_packet); vg_device.ip := f_IPv4_addr_dec(vl_asp_mi.ip_header.srcaddr); vg_device.mac := vl_asp_mi.src_mac_address; vg_stamp := vl_asp_mi.mi_packet.stamp; } [] T.timeout {setverdict(fail, "Timeout on Hello answer")} } return vg_device; }
  35. 35. Implementacja - JSON (1) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. type record Command { charstring method, CharstringListOrCredentials params, integer id } type union CharstringListOrCredentials { CharstringList list, Credentials cred } with { variant "JSON: as value"; } type record Credentials { charstring ssid, charstring passwd, integer uid }
  36. 36. Implementacja - JSON (2) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. type record Result { ValueListOrCode result, integer id } type union ValueListOrCode { ValueList list, integer code } with { variant "JSON: as value"; } type record of Value ValueList; type union Value { integer i, charstring c, Null n } with { variant "JSON: as value"; }
  37. 37. Implementacja - JSON (3) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. external function f_enc_Command(in Command par) return octetstring with { extension "prototype(convert) encode(JSON)" } external function f_dec_Result(in octetstring par) return Result with { extension "prototype(convert) decode(JSON)" }
  38. 38. Implementacja - ASN.1 Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. Null DEFINITIONS -- [(AUTOMATIC|EXPLICIT|IMPLICIT) TAGS] -- the default is EXPLICIT TAGS AUTOMATIC TAGS ::= BEGIN IMPORTS ; Null ::= NULL END
  39. 39. Implementacja - Command templates Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. template Command t_cmd_config_router := { method := "miIO.config_router", params := {cred := {tsp_ssid,tsp_passwd,tsp_uid}}, id := -1 } template Command t_cmd_power_on := { method := "set_power", params := {list := {"on"}}, id := -1 } template Command t_cmd_set_mode(charstring p_mode) := { method := "set_mode", params := {list := {p_mode}}, id := -1 } template Command t_cmd_get_prop(CharstringList p_props) := { method := "get_prop", params := {list := p_props}, id := -1 }
  40. 40. Implementacja - f_s_command (1) Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_s_command(Command p_cmd, ResultVerification p_callback) runs on Mi_CT return ReturnBoolean { p_cmd.id := vg_id; if(not isbound(vg_stamp) or vg_stamp < 0) { log("No stamp from hello request"); return false; } var octetstring vl_cmd := f_enc_Command(p_cmd); var integer vl_pad := 16 - lengthof(vl_cmd) rem 16; for(var integer i := 0; i < vl_pad; i := i + 1) { vl_cmd := vl_cmd & int2oct(vl_pad, 1); } vl_cmd := f_AES_CBC_128_Encrypt_OpenSSL(vg_key, vg_iv, vl_cmd); var Mi_Packet vl_mi_packet := valueof(t_mi_Data_Packet(vl_cmd, vg_device.did, vg_stamp, vg_device.token)); vl_mi_packet.cksum := f_calculateMD5_oct(f_enc_Mi_Packet(vl_mi_packet)); var charstring vl_hostaddr := f_getIP(); Mi_Internal_PCO.send(t_asp_mi(vg_device.mac, vl_hostaddr, vg_device.ip, vg_device.portnum, vl_mi_packet)); T.start(1.0);
  41. 41. Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. var ASP_Mi vl_asp_mi; alt { [] Mi_Internal_PCO.receive(ASP_Mi:?) -> value vl_asp_mi { T.stop; var OCT16 vl_cksum := vl_asp_mi.mi_packet.cksum; vl_asp_mi.mi_packet.cksum := vg_device.token; if(not match(f_calculateMD5_oct(f_enc_Mi_Packet(vl_asp_mi.mi_packet)), vl_cksum)) { setverdict(fail, "Incorrect checksum"); log("Incorrect checksum: ", match(vl_cksum, f_calculateMD5_oct(f_enc_Mi_Packet(vl_asp_mi.mi_packet)))); } f_decrypt(vl_asp_mi.mi_packet.data); var Result vl_result := f_dec_Result(vl_asp_mi.mi_packet.data); if(not match(vl_result.id, vg_id)) {setverdict(fail, "Incorrect Result Id");} else { log("Received Result: ", vl_result); setverdict(pass); } p_callback.apply(vl_result); } [] T.timeout {log("Timeout on waiting for reply!")} } vg_id := vg_id + 1; return true; } Implementacja - f_s_command (2)
  42. 42. Implementacja - f_decrypt Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_decrypt(inout octetstring p_data) runs on Mi_CT { p_data := f_AES_CBC_128_Decrypt_OpenSSL(vg_key, vg_iv, p_data); var octetstring vl_last_octet := p_data[lengthof(p_data) - 1]; if(vl_last_octet == '00'O) { // remove null termination p_data := substr(p_data, 0 , lengthof(p_data) - 1); } else if(vl_last_octet != char2oct("}")) { // remove padding p_data := substr(p_data, 0 , lengthof(p_data) - oct2int(vl_last_octet)); if(vl_last_octet == '00'O) { // remove null termination p_data := substr(p_data, 0 , lengthof(p_data) - 1); } } }
  43. 43. Test powtarzalności czujników Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  44. 44. Scenariusz testowy ● Wszystkie urządzenia znajdują się w jednej sieci wi-fi ● Wysyłany jest jeden pakiet Hello ● Każde urządzenie odpowiada podając aktualny timestamp ● Do wszytkich urządzeń wysyłana jest komenda “get_props” z parametrami: “tmp_dec”, “hum”, “aqi” ● Otrzymane wartości są zapisywane i powtarzany jest poprzedni krok (po odczekaniu zdefiniowanego opóźnienia) aż do wyczerpanie limitu pomiarów ● Dla każdego parametru liczona jest średnia ucinana osobno dla każdego urządzenia ● Sprawdzane jest czy różnica pomiędzy największą a najmniejszą średnią dla danego parametru mieści w zdefiniowanym zakresie Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.
  45. 45. Architektura Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. MTC Mi Sync_PCO Mi_Internal_PCO Mi Sync_PCO Mi_Internal_PCO Mi Sync_PCO Mi_Internal_PCO Mi_External_PCO Dispatcher Sync_PCO Mi_Internal_PCO
  46. 46. Implementacja - tc_check_sensors Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. testcase tc_check_sensors() runs on MTC_CT { f_init_Mi_components(); if(vg_continue) { timer T_delay; var CharstringList vl_props := {} vl_props[cg_temp] := "temp_dec"; vl_props[cg_hum] := "humidity"; vl_props[cg_aqi] := "aqi"; var ReturnBoolean vl_continue := true; for(var integer i := 0; vl_continue and i < tsp_no_checks; i := i + 1) { for(var integer j := 0; vl_continue and j < sizeof(vg_Mi_CT_List); j := j + 1) { vg_Mi_CT_List[j].start(f_s_command(valueof(t_cmd_get_prop(vl_props)), refers(f_check_values))); vg_Mi_CT_List[j].done(ReturnBoolean:?) -> value vl_continue; } T_delay.start(tsp_check_interval); T_delay.timeout; } f_analyze_results(); } }
  47. 47. Implementacja - f_analyze_results Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_analyze_results() runs on MTC_CT { var IntegerList2 vl_temp := {}; var IntegerList2 vl_hum := {}; var IntegerList2 vl_aqi := {}; for(var integer i := 0; i < sizeof(vg_Mi_CT_List); i := i + 1) { vl_temp[i] := {}; vl_hum[i] := {}; vl_aqi[i] := {}; var IntegerList2 vl_results := {}; vg_Mi_CT_List[i].start(f_get_values()); vg_Mi_CT_List[i].done(IntegerList2:?) -> value vl_results; for(var integer j := 0; j < sizeof(vl_results); j := j + 1) { if(not isbound(vl_results[j])) {continue} if(isbound(vl_results[j][cg_temp])) { vl_temp[i][sizeof(vl_temp[i])] := vl_results[j][cg_temp]; } if(isbound(vl_results[j][cg_hum])) { vl_hum[i][sizeof(vl_hum[i])] := vl_results[j][cg_hum]; } if(isbound(vl_results[j][cg_aqi])) { vl_aqi[i][sizeof(vl_aqi[i])] := vl_results[j][cg_aqi]; } } } f_check_tolerance("Temperature", vl_temp, tsp_temp_tolerance); f_check_tolerance("Humidity", vl_hum, tsp_hum_tolerance); f_check_tolerance("AQI", vl_aqi, tsp_aqi_tolerance); }
  48. 48. Implementacja - f_check_tolerance Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. function f_check_tolerance( in charstring p_desc, inout IntegerList2 p_list, in float p_tolerance) { log(p_desc, ": All results: ", p_list); var FloatList vl_average_list := {} for(var integer i := 0; i < sizeof(p_list); i := i + 1) { f_quicksort(p_list[i], 0, sizeof(p_list[i]) - 1); if(sizeof(p_list[i]) > 2 * tsp_trimmed) { var IntegerList vl_tmp_list := {}; for (var integer x := tsp_trimmed; x < sizeof(p_list[i]) - tsp_trimmed; x := x + 1) { vl_tmp_list[x - tsp_trimmed] := p_list[i][x]; } p_list[i] := vl_tmp_list; } vl_average_list[i] := f_averageIL(p_list[i]); } log(p_desc, ": Trimmed results: ", p_list); log(p_desc, ": Average values: ", vl_average_list); var float vl_min := f_minFL(vl_average_list)[0]; var float vl_max := f_maxFL(vl_average_list)[0]; if(vl_min * (1.0 + p_tolerance / 100.0) >= vl_max) { setverdict(pass); } else { setverdict(fail, "Minimal (", vl_min, ") and maximal (", vl_max, ") values do not match tolerance condition (", p_tolerance, "%)"); } }
  49. 49. Plik konfiguracyjny Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. [INCLUDE] "network.cfg" [DEFINE] def_interface := "wlp5s0" [TESTPORT_PARAMETERS] *.DNS_PCO.eth_interface_name := $def_interface *.Mi_External_PCO.eth_interface_name := $def_interface [LOGGING] ConsoleMask := USER|ERROR|TESTCASE|STATISTICS|VERDICTOP_FINAL|VERDICTOP_UNQUALIFIED FileMask := MATCHING|DEBUG|ACTION|DEFAULTOP|ERROR|EXECUTOR|FUNCTION|PARALLEL|PORTEVENT|STATISTICS|TESTCASE|TIMEROP|USER|VERDICTOP|WARNIN G TimeStampFormat := DateTime LogEventTypes := Yes SourceInfoFormat := Stack LogEntityName := Yes LogFile := "log/%c.%n-%r.%s" *.MatchingHints := Detailed [MODULE_PARAMETERS] tsp_src_portnum := 10000 tsp_devices := { {"peppa_pig",'C8B18F9B3CACF0122BF5177D6DA51492'O,'033DDE49'O,''O,"",54321} } tsp_no_checks := 32 tsp_check_interval := 2.0 tsp_temp_tolerance := 10.0; tsp_hum_tolerance := 10.0; tsp_aqi_tolerance := 10.0; tsp_trimmed := 2;
  50. 50. Pytania i Odpowiedzi Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information. ?
  51. 51. Dziękuję za uwagę Copyright © 2018 Semihalf. All rights reserved. Confidential and proprietary information.

×