diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Device.be b/lib/libesp32/berry_matter/src/embedded/Matter_Device.be index d272c4061e43..cbbdba2dcd3e 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Device.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Device.be @@ -886,7 +886,7 @@ class Matter_Device # Add Hostname (based on MAC) with IPv4/IPv6 addresses var eth = tasmota.eth() self.hostname_eth = string.replace(eth.find("mac"), ':', '') - if !self.ipv4only + if !self.ipv4only || !eth.contains('ip6local') # tasmota.log(format("MTR: calling mdns.add_hostname(%s, %s, %s)", self.hostname_eth, eth.find('ip6local',''), eth.find('ip','')), 4) mdns.add_hostname(self.hostname_eth, eth.find('ip6local',''), eth.find('ip',''), eth.find('ip6','')) else @@ -896,11 +896,11 @@ class Matter_Device else var wifi = tasmota.wifi() self.hostname_wifi = string.replace(wifi.find("mac"), ':', '') - if !self.ipv4only + if !self.ipv4only || !wifi.contains('ip6local') # tasmota.log(format("MTR: calling mdns.add_hostname(%s, %s, %s)", self.hostname_wifi, wifi.find('ip6local',''), wifi.find('ip','')), 4) mdns.add_hostname(self.hostname_wifi, wifi.find('ip6local',''), wifi.find('ip',''), wifi.find('ip6','')) else - tasmota.log(format("MTR: calling mdns.add_hostname(%s, %s)", self.hostname_eth, wifi.find('ip','')), 3) + tasmota.log(format("MTR: calling mdns.add_hostname(%s, %s)", self.hostname_wifi, wifi.find('ip','')), 3) mdns.add_hostname(self.hostname_wifi, wifi.find('ip','')) end end diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Device.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Device.h index 32377c2c9f30..660a2b85b615 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Device.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Device.h @@ -3540,7 +3540,7 @@ be_local_closure(Matter_Device__mdns_announce_hostname, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[26]) { /* constants */ + ( &(const bvalue[27]) { /* constants */ /* K0 */ be_nested_str_weak(mdns), /* K1 */ be_nested_str_weak(string), /* K2 */ be_nested_str_weak(start), @@ -3553,30 +3553,31 @@ be_local_closure(Matter_Device__mdns_announce_hostname, /* name */ /* K9 */ be_nested_str_weak(_X3A), /* K10 */ be_nested_str_weak(), /* K11 */ be_nested_str_weak(ipv4only), - /* K12 */ be_nested_str_weak(add_hostname), + /* K12 */ be_nested_str_weak(contains), /* K13 */ be_nested_str_weak(ip6local), - /* K14 */ be_nested_str_weak(ip), - /* K15 */ be_nested_str_weak(ip6), - /* K16 */ be_nested_str_weak(log), - /* K17 */ be_nested_str_weak(MTR_X3A_X20calling_X20mdns_X2Eadd_hostname_X28_X25s_X2C_X20_X25s_X29), - /* K18 */ be_const_int(3), - /* K19 */ be_nested_str_weak(wifi), - /* K20 */ be_nested_str_weak(hostname_wifi), - /* K21 */ be_nested_str_weak(MTR_X3A_X20start_X20mDNS_X20on_X20_X25s_X20host_X20_X27_X25s_X2Elocal_X27), - /* K22 */ be_nested_str_weak(MTR_X3A_X20Exception), - /* K23 */ be_nested_str_weak(_X7C), - /* K24 */ be_const_int(2), - /* K25 */ be_nested_str_weak(mdns_announce_op_discovery_all_fabrics), + /* K14 */ be_nested_str_weak(add_hostname), + /* K15 */ be_nested_str_weak(ip), + /* K16 */ be_nested_str_weak(ip6), + /* K17 */ be_nested_str_weak(log), + /* K18 */ be_nested_str_weak(MTR_X3A_X20calling_X20mdns_X2Eadd_hostname_X28_X25s_X2C_X20_X25s_X29), + /* K19 */ be_const_int(3), + /* K20 */ be_nested_str_weak(wifi), + /* K21 */ be_nested_str_weak(hostname_wifi), + /* K22 */ be_nested_str_weak(MTR_X3A_X20start_X20mDNS_X20on_X20_X25s_X20host_X20_X27_X25s_X2Elocal_X27), + /* K23 */ be_nested_str_weak(MTR_X3A_X20Exception), + /* K24 */ be_nested_str_weak(_X7C), + /* K25 */ be_const_int(2), + /* K26 */ be_nested_str_weak(mdns_announce_op_discovery_all_fabrics), }), be_str_weak(_mdns_announce_hostname), &be_const_str_solidified, - ( &(const binstruction[140]) { /* code */ + ( &(const binstruction[148]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 0xA40E0200, // 0001 IMPORT R3 K1 0x8C100502, // 0002 GETMET R4 R2 K2 0x7C100200, // 0003 CALL R4 1 - 0xA8020072, // 0004 EXBLK 0 #0078 - 0x78060030, // 0005 JMPF R1 #0037 + 0xA802007A, // 0004 EXBLK 0 #0080 + 0x78060034, // 0005 JMPF R1 #003B 0xB8120600, // 0006 GETNGBL R4 K3 0x8C100904, // 0007 GETMET R4 R4 K4 0x7C100200, // 0008 CALL R4 1 @@ -3589,128 +3590,136 @@ be_local_closure(Matter_Device__mdns_announce_hostname, /* name */ 0x7C140800, // 000F CALL R5 4 0x90020A05, // 0010 SETMBR R0 K5 R5 0x8814010B, // 0011 GETMBR R5 R0 K11 - 0x7416000F, // 0012 JMPT R5 #0023 - 0x8C14050C, // 0013 GETMET R5 R2 K12 - 0x881C0105, // 0014 GETMBR R7 R0 K5 - 0x8C200907, // 0015 GETMET R8 R4 K7 - 0x5828000D, // 0016 LDCONST R10 K13 - 0x582C000A, // 0017 LDCONST R11 K10 - 0x7C200600, // 0018 CALL R8 3 - 0x8C240907, // 0019 GETMET R9 R4 K7 - 0x582C000E, // 001A LDCONST R11 K14 - 0x5830000A, // 001B LDCONST R12 K10 - 0x7C240600, // 001C CALL R9 3 - 0x8C280907, // 001D GETMET R10 R4 K7 - 0x5830000F, // 001E LDCONST R12 K15 - 0x5834000A, // 001F LDCONST R13 K10 - 0x7C280600, // 0020 CALL R10 3 - 0x7C140A00, // 0021 CALL R5 5 - 0x70020012, // 0022 JMP #0036 - 0xB8160600, // 0023 GETNGBL R5 K3 - 0x8C140B10, // 0024 GETMET R5 R5 K16 - 0x601C0018, // 0025 GETGBL R7 G24 - 0x58200011, // 0026 LDCONST R8 K17 - 0x88240105, // 0027 GETMBR R9 R0 K5 - 0x8C280907, // 0028 GETMET R10 R4 K7 - 0x5830000E, // 0029 LDCONST R12 K14 - 0x5834000A, // 002A LDCONST R13 K10 - 0x7C280600, // 002B CALL R10 3 - 0x7C1C0600, // 002C CALL R7 3 - 0x58200012, // 002D LDCONST R8 K18 - 0x7C140600, // 002E CALL R5 3 - 0x8C14050C, // 002F GETMET R5 R2 K12 - 0x881C0105, // 0030 GETMBR R7 R0 K5 - 0x8C200907, // 0031 GETMET R8 R4 K7 - 0x5828000E, // 0032 LDCONST R10 K14 - 0x582C000A, // 0033 LDCONST R11 K10 - 0x7C200600, // 0034 CALL R8 3 - 0x7C140600, // 0035 CALL R5 3 - 0x7002002F, // 0036 JMP #0067 - 0xB8120600, // 0037 GETNGBL R4 K3 - 0x8C100913, // 0038 GETMET R4 R4 K19 - 0x7C100200, // 0039 CALL R4 1 - 0x8C140706, // 003A GETMET R5 R3 K6 - 0x8C1C0907, // 003B GETMET R7 R4 K7 - 0x58240008, // 003C LDCONST R9 K8 - 0x7C1C0400, // 003D CALL R7 2 - 0x58200009, // 003E LDCONST R8 K9 - 0x5824000A, // 003F LDCONST R9 K10 - 0x7C140800, // 0040 CALL R5 4 - 0x90022805, // 0041 SETMBR R0 K20 R5 - 0x8814010B, // 0042 GETMBR R5 R0 K11 - 0x7416000F, // 0043 JMPT R5 #0054 - 0x8C14050C, // 0044 GETMET R5 R2 K12 - 0x881C0114, // 0045 GETMBR R7 R0 K20 - 0x8C200907, // 0046 GETMET R8 R4 K7 - 0x5828000D, // 0047 LDCONST R10 K13 - 0x582C000A, // 0048 LDCONST R11 K10 - 0x7C200600, // 0049 CALL R8 3 - 0x8C240907, // 004A GETMET R9 R4 K7 - 0x582C000E, // 004B LDCONST R11 K14 - 0x5830000A, // 004C LDCONST R12 K10 - 0x7C240600, // 004D CALL R9 3 - 0x8C280907, // 004E GETMET R10 R4 K7 - 0x5830000F, // 004F LDCONST R12 K15 - 0x5834000A, // 0050 LDCONST R13 K10 - 0x7C280600, // 0051 CALL R10 3 - 0x7C140A00, // 0052 CALL R5 5 - 0x70020012, // 0053 JMP #0067 - 0xB8160600, // 0054 GETNGBL R5 K3 - 0x8C140B10, // 0055 GETMET R5 R5 K16 - 0x601C0018, // 0056 GETGBL R7 G24 - 0x58200011, // 0057 LDCONST R8 K17 - 0x88240105, // 0058 GETMBR R9 R0 K5 - 0x8C280907, // 0059 GETMET R10 R4 K7 - 0x5830000E, // 005A LDCONST R12 K14 - 0x5834000A, // 005B LDCONST R13 K10 - 0x7C280600, // 005C CALL R10 3 - 0x7C1C0600, // 005D CALL R7 3 - 0x58200012, // 005E LDCONST R8 K18 - 0x7C140600, // 005F CALL R5 3 - 0x8C14050C, // 0060 GETMET R5 R2 K12 - 0x881C0114, // 0061 GETMBR R7 R0 K20 - 0x8C200907, // 0062 GETMET R8 R4 K7 - 0x5828000E, // 0063 LDCONST R10 K14 - 0x582C000A, // 0064 LDCONST R11 K10 - 0x7C200600, // 0065 CALL R8 3 - 0x7C140600, // 0066 CALL R5 3 - 0xB8120600, // 0067 GETNGBL R4 K3 - 0x8C100910, // 0068 GETMET R4 R4 K16 - 0x60180018, // 0069 GETGBL R6 G24 - 0x581C0015, // 006A LDCONST R7 K21 - 0x78060001, // 006B JMPF R1 #006E - 0x58200004, // 006C LDCONST R8 K4 - 0x70020000, // 006D JMP #006F - 0x58200013, // 006E LDCONST R8 K19 - 0x78060001, // 006F JMPF R1 #0072 - 0x88240105, // 0070 GETMBR R9 R0 K5 - 0x70020000, // 0071 JMP #0073 - 0x88240114, // 0072 GETMBR R9 R0 K20 - 0x7C180600, // 0073 CALL R6 3 - 0x581C0012, // 0074 LDCONST R7 K18 - 0x7C100600, // 0075 CALL R4 3 - 0xA8040001, // 0076 EXBLK 1 1 - 0x70020010, // 0077 JMP #0089 - 0xAC100002, // 0078 CATCH R4 0 2 - 0x7002000D, // 0079 JMP #0088 - 0xB81A0600, // 007A GETNGBL R6 K3 - 0x8C180D10, // 007B GETMET R6 R6 K16 - 0x60200008, // 007C GETGBL R8 G8 - 0x5C240800, // 007D MOVE R9 R4 - 0x7C200200, // 007E CALL R8 1 - 0x00222C08, // 007F ADD R8 K22 R8 - 0x00201117, // 0080 ADD R8 R8 K23 - 0x60240008, // 0081 GETGBL R9 G8 - 0x5C280A00, // 0082 MOVE R10 R5 - 0x7C240200, // 0083 CALL R9 1 - 0x00201009, // 0084 ADD R8 R8 R9 - 0x58240018, // 0085 LDCONST R9 K24 - 0x7C180600, // 0086 CALL R6 3 - 0x70020000, // 0087 JMP #0089 - 0xB0080000, // 0088 RAISE 2 R0 R0 - 0x8C100119, // 0089 GETMET R4 R0 K25 - 0x7C100200, // 008A CALL R4 1 - 0x80000000, // 008B RET 0 + 0x78160003, // 0012 JMPF R5 #0017 + 0x8C14090C, // 0013 GETMET R5 R4 K12 + 0x581C000D, // 0014 LDCONST R7 K13 + 0x7C140400, // 0015 CALL R5 2 + 0x7416000F, // 0016 JMPT R5 #0027 + 0x8C14050E, // 0017 GETMET R5 R2 K14 + 0x881C0105, // 0018 GETMBR R7 R0 K5 + 0x8C200907, // 0019 GETMET R8 R4 K7 + 0x5828000D, // 001A LDCONST R10 K13 + 0x582C000A, // 001B LDCONST R11 K10 + 0x7C200600, // 001C CALL R8 3 + 0x8C240907, // 001D GETMET R9 R4 K7 + 0x582C000F, // 001E LDCONST R11 K15 + 0x5830000A, // 001F LDCONST R12 K10 + 0x7C240600, // 0020 CALL R9 3 + 0x8C280907, // 0021 GETMET R10 R4 K7 + 0x58300010, // 0022 LDCONST R12 K16 + 0x5834000A, // 0023 LDCONST R13 K10 + 0x7C280600, // 0024 CALL R10 3 + 0x7C140A00, // 0025 CALL R5 5 + 0x70020012, // 0026 JMP #003A + 0xB8160600, // 0027 GETNGBL R5 K3 + 0x8C140B11, // 0028 GETMET R5 R5 K17 + 0x601C0018, // 0029 GETGBL R7 G24 + 0x58200012, // 002A LDCONST R8 K18 + 0x88240105, // 002B GETMBR R9 R0 K5 + 0x8C280907, // 002C GETMET R10 R4 K7 + 0x5830000F, // 002D LDCONST R12 K15 + 0x5834000A, // 002E LDCONST R13 K10 + 0x7C280600, // 002F CALL R10 3 + 0x7C1C0600, // 0030 CALL R7 3 + 0x58200013, // 0031 LDCONST R8 K19 + 0x7C140600, // 0032 CALL R5 3 + 0x8C14050E, // 0033 GETMET R5 R2 K14 + 0x881C0105, // 0034 GETMBR R7 R0 K5 + 0x8C200907, // 0035 GETMET R8 R4 K7 + 0x5828000F, // 0036 LDCONST R10 K15 + 0x582C000A, // 0037 LDCONST R11 K10 + 0x7C200600, // 0038 CALL R8 3 + 0x7C140600, // 0039 CALL R5 3 + 0x70020033, // 003A JMP #006F + 0xB8120600, // 003B GETNGBL R4 K3 + 0x8C100914, // 003C GETMET R4 R4 K20 + 0x7C100200, // 003D CALL R4 1 + 0x8C140706, // 003E GETMET R5 R3 K6 + 0x8C1C0907, // 003F GETMET R7 R4 K7 + 0x58240008, // 0040 LDCONST R9 K8 + 0x7C1C0400, // 0041 CALL R7 2 + 0x58200009, // 0042 LDCONST R8 K9 + 0x5824000A, // 0043 LDCONST R9 K10 + 0x7C140800, // 0044 CALL R5 4 + 0x90022A05, // 0045 SETMBR R0 K21 R5 + 0x8814010B, // 0046 GETMBR R5 R0 K11 + 0x78160003, // 0047 JMPF R5 #004C + 0x8C14090C, // 0048 GETMET R5 R4 K12 + 0x581C000D, // 0049 LDCONST R7 K13 + 0x7C140400, // 004A CALL R5 2 + 0x7416000F, // 004B JMPT R5 #005C + 0x8C14050E, // 004C GETMET R5 R2 K14 + 0x881C0115, // 004D GETMBR R7 R0 K21 + 0x8C200907, // 004E GETMET R8 R4 K7 + 0x5828000D, // 004F LDCONST R10 K13 + 0x582C000A, // 0050 LDCONST R11 K10 + 0x7C200600, // 0051 CALL R8 3 + 0x8C240907, // 0052 GETMET R9 R4 K7 + 0x582C000F, // 0053 LDCONST R11 K15 + 0x5830000A, // 0054 LDCONST R12 K10 + 0x7C240600, // 0055 CALL R9 3 + 0x8C280907, // 0056 GETMET R10 R4 K7 + 0x58300010, // 0057 LDCONST R12 K16 + 0x5834000A, // 0058 LDCONST R13 K10 + 0x7C280600, // 0059 CALL R10 3 + 0x7C140A00, // 005A CALL R5 5 + 0x70020012, // 005B JMP #006F + 0xB8160600, // 005C GETNGBL R5 K3 + 0x8C140B11, // 005D GETMET R5 R5 K17 + 0x601C0018, // 005E GETGBL R7 G24 + 0x58200012, // 005F LDCONST R8 K18 + 0x88240115, // 0060 GETMBR R9 R0 K21 + 0x8C280907, // 0061 GETMET R10 R4 K7 + 0x5830000F, // 0062 LDCONST R12 K15 + 0x5834000A, // 0063 LDCONST R13 K10 + 0x7C280600, // 0064 CALL R10 3 + 0x7C1C0600, // 0065 CALL R7 3 + 0x58200013, // 0066 LDCONST R8 K19 + 0x7C140600, // 0067 CALL R5 3 + 0x8C14050E, // 0068 GETMET R5 R2 K14 + 0x881C0115, // 0069 GETMBR R7 R0 K21 + 0x8C200907, // 006A GETMET R8 R4 K7 + 0x5828000F, // 006B LDCONST R10 K15 + 0x582C000A, // 006C LDCONST R11 K10 + 0x7C200600, // 006D CALL R8 3 + 0x7C140600, // 006E CALL R5 3 + 0xB8120600, // 006F GETNGBL R4 K3 + 0x8C100911, // 0070 GETMET R4 R4 K17 + 0x60180018, // 0071 GETGBL R6 G24 + 0x581C0016, // 0072 LDCONST R7 K22 + 0x78060001, // 0073 JMPF R1 #0076 + 0x58200004, // 0074 LDCONST R8 K4 + 0x70020000, // 0075 JMP #0077 + 0x58200014, // 0076 LDCONST R8 K20 + 0x78060001, // 0077 JMPF R1 #007A + 0x88240105, // 0078 GETMBR R9 R0 K5 + 0x70020000, // 0079 JMP #007B + 0x88240115, // 007A GETMBR R9 R0 K21 + 0x7C180600, // 007B CALL R6 3 + 0x581C0013, // 007C LDCONST R7 K19 + 0x7C100600, // 007D CALL R4 3 + 0xA8040001, // 007E EXBLK 1 1 + 0x70020010, // 007F JMP #0091 + 0xAC100002, // 0080 CATCH R4 0 2 + 0x7002000D, // 0081 JMP #0090 + 0xB81A0600, // 0082 GETNGBL R6 K3 + 0x8C180D11, // 0083 GETMET R6 R6 K17 + 0x60200008, // 0084 GETGBL R8 G8 + 0x5C240800, // 0085 MOVE R9 R4 + 0x7C200200, // 0086 CALL R8 1 + 0x00222E08, // 0087 ADD R8 K23 R8 + 0x00201118, // 0088 ADD R8 R8 K24 + 0x60240008, // 0089 GETGBL R9 G8 + 0x5C280A00, // 008A MOVE R10 R5 + 0x7C240200, // 008B CALL R9 1 + 0x00201009, // 008C ADD R8 R8 R9 + 0x58240019, // 008D LDCONST R9 K25 + 0x7C180600, // 008E CALL R6 3 + 0x70020000, // 008F JMP #0091 + 0xB0080000, // 0090 RAISE 2 R0 R0 + 0x8C10011A, // 0091 GETMET R4 R0 K26 + 0x7C100200, // 0092 CALL R4 1 + 0x80000000, // 0093 RET 0 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/be_mdns_module.c b/lib/libesp32/berry_tasmota/src/be_mdns_module.c new file mode 100644 index 000000000000..d0caa11b1b3a --- /dev/null +++ b/lib/libesp32/berry_tasmota/src/be_mdns_module.c @@ -0,0 +1,45 @@ +/******************************************************************** + * Berry module `mdns` + * + * To use: `import mdns` + * + * MDNS support + *******************************************************************/ +#include "be_constobj.h" +#include "be_mapping.h" +#include "be_mem.h" + +#ifdef USE_DISCOVERY + +extern void m_mdns_start(struct bvm *vm, const char* hostname); +BE_FUNC_CTYPE_DECLARE(m_mdns_start, "", "@[s]") + +extern void m_mdns_stop(void); +BE_FUNC_CTYPE_DECLARE(m_mdns_stop, "", "") + +extern void m_mdns_set_hostname(struct bvm *vm, const char * hostname); +BE_FUNC_CTYPE_DECLARE(m_mdns_set_hostname, "", "@s") + +extern int32_t m_mdns_add_service(struct bvm *vm); +extern int32_t m_mdns_remove_service(struct bvm *vm); +extern int32_t m_dns_add_subtype(struct bvm *vm); +extern int32_t m_dns_add_hostname(struct bvm *vm); +extern int32_t m_dns_find_service(struct bvm *vm); + +/* @const_object_info_begin +module mdns (scope: global) { + start, ctype_func(m_mdns_start) + stop, ctype_func(m_mdns_stop) + set_hostname, ctype_func(m_mdns_set_hostname) + add_service, func(m_mdns_add_service) + add_hostname, func(m_dns_add_hostname) + add_subtype, func(m_dns_add_subtype) + remove_service, func(m_mdns_remove_service) + + // querying + find_service, func(m_dns_find_service) +} +@const_object_info_end */ +#include "be_fixed_mdns.h" + +#endif // USE_DISCOVERY \ No newline at end of file diff --git a/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp b/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp deleted file mode 100644 index 802093a679cb..000000000000 --- a/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/******************************************************************** - * Berry module `mdns` - * - * To use: `import mdns` - * - * MDNS support - *******************************************************************/ -#include "be_constobj.h" -#include "be_mapping.h" -#include "be_mem.h" - -#ifdef USE_DISCOVERY -#include "mdns.h" -#include -#include "IPAddress.h" - -// -// `mdsn.start([hostname:string]) -> nil` -// start or restart mdns, specify hostname or use tasmota.hostname() if none provided (default) -extern char* NetworkHostname(void); -static void m_mdns_start(struct bvm *vm, const char* hostname) { - esp_err_t err = mdns_init(); - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "could not initialize mdns err=%i", err); - } - if (hostname == NULL) { - hostname = NetworkHostname(); // revert to default hostname if none is specified - } - err = mdns_hostname_set(hostname); - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "could not set hostname err=%i", err); - } -} -BE_FUNC_CTYPE_DECLARE(m_mdns_start, "", "@[s]") - -// -// `msdn.stop() -> nil` -// free all mdns resources -static void m_mdns_stop(void) { - mdns_free(); -} -BE_FUNC_CTYPE_DECLARE(m_mdns_stop, "", "") - -// -// `mdns.set_hostname(hostname:string) -> nil` -// change the hostname -static void m_mdns_set_hostname(struct bvm *vm, const char * hostname) { - esp_err_t err = mdns_hostname_set(hostname); - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "mdns set_hostname err=%i", err); - } -} -BE_FUNC_CTYPE_DECLARE(m_mdns_set_hostname, "", "@s") - -// -// `mdns.add_service(service:string, proto:string, port:int, txt:map [, instance:string, hostname:string]) -> nil` -// -// add a service declaration using the current hostname as instance name, and specify TXT fields as a `map` -// -// Test: -// import mdns mdns.add_service("_arduino","_tcp",1111, {"board":"tasmota", "tcp_check":"no", "ssh_upload":"no", "auth_upload":"no"}) -// -// import mdns mdns.add_service("_matterc","_udp", 5540, {"VP":"65521+32768", "SII":5000, "SAI":300, "T":1, "D":3840, "CM":1, "PH":33, "PI":""}) -static int32_t m_mdns_add_service(struct bvm *vm) { - int32_t top = be_top(vm); - if (top >= 3 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isint(vm, 3)) { - const char* service_type = be_tostring(vm, 1); - const char* proto = be_tostring(vm, 2); - uint16_t port = be_toint(vm, 3); - const char * instance = nullptr; - const char * hostname = nullptr; - if (top >= 5 && be_isstring(vm, 5)) { - instance = be_tostring(vm, 5); - } - if (top >= 6 && be_isstring(vm, 6)) { - hostname = be_tostring(vm, 6); - } - - mdns_txt_item_t * txt_items = NULL; - int32_t txt_num = 0; - if (top >= 4 && be_ismapinstance(vm, 4)) { - // parse txt map - be_getmember(vm, 4, ".p"); - int32_t map_len = be_data_size(vm, -1); - if (map_len > 0) { - uint32_t i= 0; - txt_items = (mdns_txt_item_t*) be_os_malloc(sizeof(mdns_txt_item_t) * map_len); - if (txt_items != NULL) { - be_pushiter(vm, -1); /* map iterator use 1 register */ - while (be_iter_hasnext(vm, -2) && i < map_len) { - be_iter_next(vm, -2); - const char* key = be_tostring(vm, -2); - const char* val = be_tostring(vm, -1); - size_t key_len = strlen(key)+1; - txt_items[i].key = (const char*)be_os_malloc(key_len); - if (txt_items[i].key) { strcpy((char*)txt_items[i].key, key); } - size_t val_len = strlen(val)+1; - txt_items[i].value = (const char*)be_os_malloc(val_len); - if (txt_items[i].value) { strcpy((char*)txt_items[i].value, val); } - be_pop(vm, 2); - i++; - } - txt_num = i; - } else { - txt_num = 0; // failed to allocate, pretend it's empty - } - be_pop(vm, 1); /* pop iterator */ - } - } - esp_err_t err; - if (hostname == nullptr) { - err = mdns_service_add(instance, service_type, proto, port, txt_items, txt_num); - } else { - err = mdns_service_add_for_host(instance, service_type, proto, hostname, port, txt_items, txt_num); - } - // free all allocated memory - if (txt_items != NULL) { - for (uint32_t i = 0; i < txt_num; i++) { - if (txt_items[i].key != NULL) { be_os_free((void*)txt_items[i].key); } - if (txt_items[i].value != NULL) { be_os_free((void*)txt_items[i].value); } - } - be_os_free(txt_items); - } - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "mdns service_add err=%i", err); - } - be_return_nil(vm); - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - - -// -// `mdns.remove_service(service:string, proto:string [, instance:string, hostname:string]) -> nil` -// -// remove service from mDNS server with hostname. -// -// Test: -// import mdns mdns.remove_service("_arduino","_tcp") -// -// import mdns mdns.remove_service("_matterc","_udp") -static int32_t m_mdns_remove_service(struct bvm *vm) { - int32_t top = be_top(vm); - if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { - const char* service_type = be_tostring(vm, 1); - const char* proto = be_tostring(vm, 2); - const char * instance = nullptr; - const char * hostname = nullptr; - if (top >= 3 && be_isstring(vm, 3)) { - instance = be_tostring(vm, 3); - } - if (top >= 4 && be_isstring(vm, 4)) { - hostname = be_tostring(vm, 4); - } - - esp_err_t err; - if (hostname == nullptr) { - err = mdns_service_remove(service_type, proto); - } else { - err = mdns_service_remove_for_host(instance, service_type, proto, hostname); - } - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "mdns service_remove err=%i", err); - } - be_return_nil(vm); - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - -// `mdns_service_subtype_add_for_host()` is only available in most recent esp-protocols version -// -// This alias makes sure that the compilation succeeds even if the function is not available -// -extern "C" esp_err_t __tasmota_mdns_service_subtype_add_for_host (const char *instance_name, const char *service_type, const char *proto, const char *hostname, const char *subtype) -{ return ESP_OK; } -extern "C" esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, const char *subtype) __attribute__ ((weak, alias ("__tasmota_mdns_service_subtype_add_for_host"))); - -// -// `mdns.add_subtype(service:string, proto:string, instance:string, hostname:string, subtype:string) -> nil` -// -// add a subtype -// -static int32_t m_dns_add_subtype(struct bvm *vm) { - int32_t top = be_top(vm); - if (top >= 5 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isstring(vm, 3) && be_isstring(vm, 4) && be_isstring(vm, 5)) { - const char* service_type = be_tostring(vm, 1); - const char* proto = be_tostring(vm, 2); - const char* instance = be_tostring(vm, 3); - const char* hostname = be_tostring(vm, 4); - const char* subtype = be_tostring(vm, 5); - - esp_err_t err; - // Waiting for support of `mdns_service_subtype_add_for_host()` - err = mdns_service_subtype_add_for_host(instance, service_type, proto, hostname, subtype); - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "mdns add_subtype err=%i", err); - } - be_return_nil(vm); - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - -// -// `mdns.add_hostname(hostname:string, ip:string [, ip:string]*) -> nil` -// -// add a delegate hostname -// -static int32_t m_dns_add_hostname(struct bvm *vm) { - int32_t top = be_top(vm); - if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { - mdns_ip_addr_t * head = nullptr; // head of the linked list of addresses - esp_err_t err = ESP_OK; // return status - - const char* hostname = be_tostring(vm, 1); - const char* ip_text = nullptr; - for (uint16_t i = 2; i <= top; i++) { - const char* ip_text = be_tostring(vm, i); - if (ip_text == nullptr || ip_text[0] == 0) { continue; } // ignore empty string - IPAddress ip; - if (!ip.fromString(ip_text)) { err = -1; break; } - - // allocate new slot - mdns_ip_addr_t *new_head = (mdns_ip_addr_t*) be_os_malloc(sizeof(mdns_ip_addr_t)); - if (new_head == nullptr) { err = -2; break; } - new_head->next = head; - head = new_head; - -#ifdef USE_IPV6 - // - ip_addr_t *ip_addr = (ip_addr_t*) ip; - head->addr.type = ip_addr->type; - if (ip_addr->type == ESP_IPADDR_TYPE_V6) { - memcpy(head->addr.u_addr.ip6.addr, ip_addr->u_addr.ip6.addr, 16); - } else { - head->addr.u_addr.ip4.addr = ip_addr->u_addr.ip4.addr; - } -#else - head->addr.u_addr.ip4.addr = (uint32_t) ip; -#endif - } while (0); - - if (err == ESP_OK && head != nullptr) { - err = mdns_delegate_hostname_add(hostname, head); - } - - // deallocate all memory - while (head != nullptr) { - mdns_ip_addr_t * next = head->next; - be_os_free(head); - head = next; - } - - if (err == -1) { - be_raisef(vm, "value_error", "Invalid IP Address '%s'", ip_text); - } else if (err == -2) { - be_raise(vm, "memory_error", nullptr); - } else if (err != ESP_OK) { - be_raisef(vm, "value_error", "mdns_delegate_hostname_add err=%i", err); - } - be_return_nil(vm); - - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - -// -// `mdns.find_service(service:string, proto:string [timeout_ms:int(3000), max_responses:int(20)]) -> map` -// -static int32_t m_dns_find_service(struct bvm *vm) { - static const char * ip_protocol_str[] = {"v4", "v6", "max"}; - int32_t top = be_top(vm); - if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { - const char* service_name = be_tostring(vm, 1); - const char* proto = be_tostring(vm, 2); - int32_t timeout_ms = 3000; - if (top >= 3 && be_isint(vm, 3)) { - timeout_ms = be_toint(vm, 3); - } - int32_t max_responses = 20; - if (top >= 4 && be_isint(vm, 4)) { - max_responses = be_toint(vm, 4); - } - - mdns_result_t * results = NULL; - esp_err_t err = mdns_query_ptr(service_name, proto, timeout_ms, max_responses, &results); - if (err != ESP_OK) { be_raisef(vm, "value_error", "mdns_query_ptr err=%i", err); } - if (results == NULL) { be_return_nil(vm); } - - mdns_result_t * r = results; - mdns_ip_addr_t * a = NULL; - be_newobject(vm, "list"); - while (r) { - be_newobject(vm, "map"); - be_map_insert_str(vm, "type", ip_protocol_str[r->ip_protocol]); - if (r->instance_name) { be_map_insert_str(vm, "instance", r->instance_name); } - if (r->hostname) { be_map_insert_str(vm, "hostname", r->hostname); } - // TXT - be_pushstring(vm, "txt"); - be_newobject(vm, "map"); - for (int32_t t=0; t < r->txt_count; t++){ - be_map_insert_str(vm, r->txt[t].key, r->txt[t].value); - } - // - be_pop(vm, 1); - be_data_insert(vm, -3); - be_pop(vm, 2); - // - - // IP addresses - be_pushstring(vm, "ip"); - be_newobject(vm, "list"); - // - for (a = r->addr; a != NULL; a = a->next) { -#ifdef USE_IPV6 - ip_addr_t ip_addr; - if (a->addr.type == IPADDR_TYPE_V6) { - ip_addr_copy_from_ip6(ip_addr, a->addr.u_addr.ip6); - } else if (a->addr.type == IPADDR_TYPE_V4) { - ip_addr_copy_from_ip4(ip_addr, a->addr.u_addr.ip4); - } else { - continue; - } -#else - uint32_t ip_addr = a->addr.u_addr.ip4.addr; -#endif - be_pushstring(vm, IPAddress(ip_addr).toString().c_str()); - be_data_push(vm, -2); - be_pop(vm, 1); - } - // - be_pop(vm, 1); - be_data_insert(vm, -3); - be_pop(vm, 2); - - be_pop(vm, 1); - be_data_push(vm, -2); - be_pop(vm, 1); - - r = r->next; - } - be_pop(vm, 1); // now list is on top - - mdns_query_results_free(results); - be_return(vm); - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - -/* @const_object_info_begin -module mdns (scope: global) { - start, ctype_func(m_mdns_start) - stop, ctype_func(m_mdns_stop) - set_hostname, ctype_func(m_mdns_set_hostname) - add_service, func(m_mdns_add_service) - add_hostname, func(m_dns_add_hostname) - add_subtype, func(m_dns_add_subtype) - remove_service, func(m_mdns_remove_service) - - // querying - find_service, func(m_dns_find_service) -} -@const_object_info_end */ -#include "be_fixed_mdns.h" - -#endif // USE_DISCOVERY \ No newline at end of file diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.c b/lib/libesp32/berry_tasmota/src/be_udp_lib.c new file mode 100644 index 000000000000..9c58315cf098 --- /dev/null +++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.c @@ -0,0 +1,42 @@ +/******************************************************************** + * UDP lib + * + * To use: `d = udp()` + * + *******************************************************************/ +#include "be_constobj.h" + +#ifdef USE_WEBCLIENT + +extern int be_udp_init(struct bvm *vm); +extern int be_udp_deinit(struct bvm *vm); +extern int be_udp_begin(struct bvm *vm); +extern int be_udp_stop(struct bvm *vm); +extern int be_udp_begin_mcast(struct bvm *vm); +extern int be_udp_send(struct bvm *vm); +extern int be_udp_send_mcast(struct bvm *vm); +extern int be_udp_read(struct bvm *vm); + +#include "be_mapping.h" +#include "be_fixed_be_class_udp.h" + +/* @const_object_info_begin + +class be_class_udp (scope: global, name: udp) { + .p, var + remote_ip, var + remote_port, var + init, func(be_udp_init) + deinit, func(be_udp_deinit) + + send, func(be_udp_send) + send_multicast, func(be_udp_send_mcast) + + begin, func(be_udp_begin) + begin_multicast, func(be_udp_begin_mcast) + read, func(be_udp_read) + close, func(be_udp_stop) +} +@const_object_info_end */ + +#endif // USE_WEBCLIENT diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_mdns.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_mdns.ino new file mode 100644 index 000000000000..d9f59c7569e3 --- /dev/null +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_mdns.ino @@ -0,0 +1,363 @@ +/* + xdrv_52_3_berry_mdns.ino - Berry scripting language, mDNS + + Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +// also includes tcp_client + +#ifdef USE_BERRY +#ifdef USE_DISCOVERY + +#include "mdns.h" +#include +#include "IPAddress.h" + +extern "C" { + // + // `mdsn.start([hostname:string]) -> nil` + // start or restart mdns, specify hostname or use tasmota.hostname() if none provided (default) + void m_mdns_start(struct bvm *vm, const char* hostname) { + esp_err_t err = mdns_init(); + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "could not initialize mdns err=%i", err); + } + if (hostname == NULL) { + hostname = NetworkHostname(); // revert to default hostname if none is specified + } + err = mdns_hostname_set(hostname); + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "could not set hostname err=%i", err); + } + } + BE_FUNC_CTYPE_DECLARE(m_mdns_start, "", "@[s]") + + // + // `msdn.stop() -> nil` + // free all mdns resources + void m_mdns_stop(void) { + mdns_free(); + } + BE_FUNC_CTYPE_DECLARE(m_mdns_stop, "", "") + + // + // `mdns.set_hostname(hostname:string) -> nil` + // change the hostname + void m_mdns_set_hostname(struct bvm *vm, const char * hostname) { + esp_err_t err = mdns_hostname_set(hostname); + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "mdns set_hostname err=%i", err); + } + } + BE_FUNC_CTYPE_DECLARE(m_mdns_set_hostname, "", "@s") + + // + // `mdns.add_service(service:string, proto:string, port:int, txt:map [, instance:string, hostname:string]) -> nil` + // + // add a service declaration using the current hostname as instance name, and specify TXT fields as a `map` + // + // Test: + // import mdns mdns.add_service("_arduino","_tcp",1111, {"board":"tasmota", "tcp_check":"no", "ssh_upload":"no", "auth_upload":"no"}) + // + // import mdns mdns.add_service("_matterc","_udp", 5540, {"VP":"65521+32768", "SII":5000, "SAI":300, "T":1, "D":3840, "CM":1, "PH":33, "PI":""}) + int32_t m_mdns_add_service(struct bvm *vm) { + int32_t top = be_top(vm); + if (top >= 3 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isint(vm, 3)) { + const char* service_type = be_tostring(vm, 1); + const char* proto = be_tostring(vm, 2); + uint16_t port = be_toint(vm, 3); + const char * instance = nullptr; + const char * hostname = nullptr; + if (top >= 5 && be_isstring(vm, 5)) { + instance = be_tostring(vm, 5); + } + if (top >= 6 && be_isstring(vm, 6)) { + hostname = be_tostring(vm, 6); + } + + mdns_txt_item_t * txt_items = NULL; + int32_t txt_num = 0; + if (top >= 4 && be_ismapinstance(vm, 4)) { + // parse txt map + be_getmember(vm, 4, ".p"); + int32_t map_len = be_data_size(vm, -1); + if (map_len > 0) { + uint32_t i= 0; + txt_items = (mdns_txt_item_t*) be_os_malloc(sizeof(mdns_txt_item_t) * map_len); + if (txt_items != NULL) { + be_pushiter(vm, -1); /* map iterator use 1 register */ + while (be_iter_hasnext(vm, -2) && i < map_len) { + be_iter_next(vm, -2); + const char* key = be_tostring(vm, -2); + const char* val = be_tostring(vm, -1); + size_t key_len = strlen(key)+1; + txt_items[i].key = (const char*)be_os_malloc(key_len); + if (txt_items[i].key) { strcpy((char*)txt_items[i].key, key); } + size_t val_len = strlen(val)+1; + txt_items[i].value = (const char*)be_os_malloc(val_len); + if (txt_items[i].value) { strcpy((char*)txt_items[i].value, val); } + be_pop(vm, 2); + i++; + } + txt_num = i; + } else { + txt_num = 0; // failed to allocate, pretend it's empty + } + be_pop(vm, 1); /* pop iterator */ + } + } + esp_err_t err; + if (hostname == nullptr) { + err = mdns_service_add(instance, service_type, proto, port, txt_items, txt_num); + } else { + err = mdns_service_add_for_host(instance, service_type, proto, hostname, port, txt_items, txt_num); + } + // free all allocated memory + if (txt_items != NULL) { + for (uint32_t i = 0; i < txt_num; i++) { + if (txt_items[i].key != NULL) { be_os_free((void*)txt_items[i].key); } + if (txt_items[i].value != NULL) { be_os_free((void*)txt_items[i].value); } + } + be_os_free(txt_items); + } + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "mdns service_add err=%i", err); + } + be_return_nil(vm); + } + be_raise(vm, "value_error", "wrong or missing arguments"); + } + + + // + // `mdns.remove_service(service:string, proto:string [, instance:string, hostname:string]) -> nil` + // + // remove service from mDNS server with hostname. + // + // Test: + // import mdns mdns.remove_service("_arduino","_tcp") + // + // import mdns mdns.remove_service("_matterc","_udp") + int32_t m_mdns_remove_service(struct bvm *vm) { + int32_t top = be_top(vm); + if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { + const char* service_type = be_tostring(vm, 1); + const char* proto = be_tostring(vm, 2); + const char * instance = nullptr; + const char * hostname = nullptr; + if (top >= 3 && be_isstring(vm, 3)) { + instance = be_tostring(vm, 3); + } + if (top >= 4 && be_isstring(vm, 4)) { + hostname = be_tostring(vm, 4); + } + + esp_err_t err; + if (hostname == nullptr) { + err = mdns_service_remove(service_type, proto); + } else { + err = mdns_service_remove_for_host(instance, service_type, proto, hostname); + } + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "mdns service_remove err=%i", err); + } + be_return_nil(vm); + } + be_raise(vm, "value_error", "wrong or missing arguments"); + } + + // `mdns_service_subtype_add_for_host()` is only available in most recent esp-protocols version + // + // This alias makes sure that the compilation succeeds even if the function is not available + // + extern "C" esp_err_t __tasmota_mdns_service_subtype_add_for_host (const char *instance_name, const char *service_type, const char *proto, const char *hostname, const char *subtype) + { return ESP_OK; } + extern "C" esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, const char *subtype) __attribute__ ((weak, alias ("__tasmota_mdns_service_subtype_add_for_host"))); + + // + // `mdns.add_subtype(service:string, proto:string, instance:string, hostname:string, subtype:string) -> nil` + // + // add a subtype + // + int32_t m_dns_add_subtype(struct bvm *vm) { + int32_t top = be_top(vm); + if (top >= 5 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isstring(vm, 3) && be_isstring(vm, 4) && be_isstring(vm, 5)) { + const char* service_type = be_tostring(vm, 1); + const char* proto = be_tostring(vm, 2); + const char* instance = be_tostring(vm, 3); + const char* hostname = be_tostring(vm, 4); + const char* subtype = be_tostring(vm, 5); + + esp_err_t err; + // Waiting for support of `mdns_service_subtype_add_for_host()` + err = mdns_service_subtype_add_for_host(instance, service_type, proto, hostname, subtype); + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "mdns add_subtype err=%i", err); + } + be_return_nil(vm); + } + be_raise(vm, "value_error", "wrong or missing arguments"); + } + + // + // `mdns.add_hostname(hostname:string, ip:string [, ip:string]*) -> nil` + // + // add a delegate hostname + // + int32_t m_dns_add_hostname(struct bvm *vm) { + int32_t top = be_top(vm); + if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { + mdns_ip_addr_t * head = nullptr; // head of the linked list of addresses + esp_err_t err = ESP_OK; // return status + + const char* hostname = be_tostring(vm, 1); + const char* ip_text = nullptr; + for (uint16_t i = 2; i <= top; i++) { + const char* ip_text = be_tostring(vm, i); + if (ip_text == nullptr || ip_text[0] == 0) { continue; } // ignore empty string + IPAddress ip; + if (!ip.fromString(ip_text)) { err = -1; break; } + + // allocate new slot + mdns_ip_addr_t *new_head = (mdns_ip_addr_t*) be_os_malloc(sizeof(mdns_ip_addr_t)); + if (new_head == nullptr) { err = -2; break; } + new_head->next = head; + head = new_head; + + #ifdef USE_IPV6 + // + ip_addr_t *ip_addr = (ip_addr_t*) ip; + head->addr.type = ip_addr->type; + if (ip_addr->type == ESP_IPADDR_TYPE_V6) { + memcpy(head->addr.u_addr.ip6.addr, ip_addr->u_addr.ip6.addr, 16); + } else { + head->addr.u_addr.ip4.addr = ip_addr->u_addr.ip4.addr; + } + #else + head->addr.u_addr.ip4.addr = (uint32_t) ip; + #endif + } while (0); + + if (err == ESP_OK && head != nullptr) { + err = mdns_delegate_hostname_add(hostname, head); + } + + // deallocate all memory + while (head != nullptr) { + mdns_ip_addr_t * next = head->next; + be_os_free(head); + head = next; + } + + if (err == -1) { + be_raisef(vm, "value_error", "Invalid IP Address '%s'", ip_text); + } else if (err == -2) { + be_raise(vm, "memory_error", nullptr); + } else if (err != ESP_OK) { + be_raisef(vm, "value_error", "mdns_delegate_hostname_add err=%i", err); + } + be_return_nil(vm); + + } + be_raise(vm, "value_error", "wrong or missing arguments"); + } + + // + // `mdns.find_service(service:string, proto:string [timeout_ms:int(3000), max_responses:int(20)]) -> map` + // + int32_t m_dns_find_service(struct bvm *vm) { + static const char * ip_protocol_str[] = {"v4", "v6", "max"}; + int32_t top = be_top(vm); + if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { + const char* service_name = be_tostring(vm, 1); + const char* proto = be_tostring(vm, 2); + int32_t timeout_ms = 3000; + if (top >= 3 && be_isint(vm, 3)) { + timeout_ms = be_toint(vm, 3); + } + int32_t max_responses = 20; + if (top >= 4 && be_isint(vm, 4)) { + max_responses = be_toint(vm, 4); + } + + mdns_result_t * results = NULL; + esp_err_t err = mdns_query_ptr(service_name, proto, timeout_ms, max_responses, &results); + if (err != ESP_OK) { be_raisef(vm, "value_error", "mdns_query_ptr err=%i", err); } + if (results == NULL) { be_return_nil(vm); } + + mdns_result_t * r = results; + mdns_ip_addr_t * a = NULL; + be_newobject(vm, "list"); + while (r) { + be_newobject(vm, "map"); + be_map_insert_str(vm, "type", ip_protocol_str[r->ip_protocol]); + if (r->instance_name) { be_map_insert_str(vm, "instance", r->instance_name); } + if (r->hostname) { be_map_insert_str(vm, "hostname", r->hostname); } + // TXT + be_pushstring(vm, "txt"); + be_newobject(vm, "map"); + for (int32_t t=0; t < r->txt_count; t++){ + be_map_insert_str(vm, r->txt[t].key, r->txt[t].value); + } + // + be_pop(vm, 1); + be_data_insert(vm, -3); + be_pop(vm, 2); + // + + // IP addresses + be_pushstring(vm, "ip"); + be_newobject(vm, "list"); + // + for (a = r->addr; a != NULL; a = a->next) { + #ifdef USE_IPV6 + ip_addr_t ip_addr; + if (a->addr.type == IPADDR_TYPE_V6) { + ip_addr_copy_from_ip6(ip_addr, a->addr.u_addr.ip6); + } else if (a->addr.type == IPADDR_TYPE_V4) { + ip_addr_copy_from_ip4(ip_addr, a->addr.u_addr.ip4); + } else { + continue; + } + #else + uint32_t ip_addr = a->addr.u_addr.ip4.addr; + #endif + be_pushstring(vm, IPAddress(ip_addr).toString().c_str()); + be_data_push(vm, -2); + be_pop(vm, 1); + } + // + be_pop(vm, 1); + be_data_insert(vm, -3); + be_pop(vm, 2); + + be_pop(vm, 1); + be_data_push(vm, -2); + be_pop(vm, 1); + + r = r->next; + } + be_pop(vm, 1); // now list is on top + + mdns_query_results_free(results); + be_return(vm); + } + be_raise(vm, "value_error", "wrong or missing arguments"); + } +} + +#endif // USE_DISCOVERY +#endif // USE_BERRY diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_udp.ino similarity index 79% rename from lib/libesp32/berry_tasmota/src/be_udp_lib.cpp rename to tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_udp.ino index 370993a8c191..bf103d1a7545 100644 --- a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_udp.ino @@ -1,10 +1,26 @@ -/******************************************************************** - * UDP lib - * - * To use: `d = udp()` - * - *******************************************************************/ -#include "be_constobj.h" +/* + xdrv_52_3_berry_udp.ino - Berry scripting language, UDP client + + Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +// also includes tcp_client + +#ifdef USE_BERRY + #ifdef USE_WEBCLIENT @@ -17,19 +33,19 @@ #include #include "be_mapping.h" -// Tasmota Logging -extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); -enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; - extern bool WifiHostByName(const char* aHostname, IPAddress & aResult); extern "C" { // init() WiFiUDP *be_udp_init_ntv(void) { - return new WiFiUDP(); +AddLog(LOG_LEVEL_INFO, "be_udp_init_ntv start"); + WiFiUDP *udp = new WiFiUDP(); +AddLog(LOG_LEVEL_INFO, "be_udp_init_ntv udp=%p", udp); + return udp; } int32_t be_udp_init(struct bvm *vm) { +AddLog(LOG_LEVEL_INFO, "be_udp_init start"); return be_call_c_func(vm, (void*) &be_udp_init_ntv, "+.p", ""); } @@ -149,32 +165,7 @@ extern "C" { be_return_nil(vm); } } - - #include "be_fixed_be_class_udp.h" - - void be_load_udp_lib(bvm *vm) { - be_pushntvclass(vm, &be_class_udp); - be_setglobal(vm, "udp"); - be_pop(vm, 1); - } -} -/* @const_object_info_begin - -class be_class_udp (scope: global, name: udp) { - .p, var - remote_ip, var - remote_port, var - init, func(be_udp_init) - deinit, func(be_udp_deinit) - - send, func(be_udp_send) - send_multicast, func(be_udp_send_mcast) - - begin, func(be_udp_begin) - begin_multicast, func(be_udp_begin_mcast) - read, func(be_udp_read) - close, func(be_udp_stop) } -@const_object_info_end */ #endif // USE_WEBCLIENT +#endif // USE_BERRY