meshcore 2.2.22__tar.gz → 2.2.23__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. {meshcore-2.2.22 → meshcore-2.2.23}/PKG-INFO +1 -1
  2. {meshcore-2.2.22 → meshcore-2.2.23}/pyproject.toml +1 -1
  3. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/commands/contact.py +31 -10
  4. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/reader.py +35 -5
  5. {meshcore-2.2.22 → meshcore-2.2.23}/.github/python-test.yml +0 -0
  6. {meshcore-2.2.22 → meshcore-2.2.23}/.gitignore +0 -0
  7. {meshcore-2.2.22 → meshcore-2.2.23}/LICENSE +0 -0
  8. {meshcore-2.2.22 → meshcore-2.2.23}/README.md +0 -0
  9. {meshcore-2.2.22 → meshcore-2.2.23}/examples/.pubsub_example.py.swp +0 -0
  10. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_chat.py +0 -0
  11. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_pin_pairing_example.py +0 -0
  12. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_private_key_export.py +0 -0
  13. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_sign_example.py +0 -0
  14. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_stats.py +0 -0
  15. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_t1000_chan_msg.py +0 -0
  16. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_t1000_custom_vars.py +0 -0
  17. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_t1000_infos.py +0 -0
  18. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_t1000_msg.py +0 -0
  19. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_t1000_msg_retries.py +0 -0
  20. {meshcore-2.2.22 → meshcore-2.2.23}/examples/ble_t1000_set_cv.py +0 -0
  21. {meshcore-2.2.22 → meshcore-2.2.23}/examples/chan_recv_with_path.py +0 -0
  22. {meshcore-2.2.22 → meshcore-2.2.23}/examples/connection_events_example.py +0 -0
  23. {meshcore-2.2.22 → meshcore-2.2.23}/examples/mepo_mc_gps.py +0 -0
  24. {meshcore-2.2.22 → meshcore-2.2.23}/examples/pubsub_example.py +0 -0
  25. {meshcore-2.2.22 → meshcore-2.2.23}/examples/rf_packet_monitor.py +0 -0
  26. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_battery_monitor.py +0 -0
  27. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_channel_manager.py +0 -0
  28. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_chat.py +0 -0
  29. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_contacts.py +0 -0
  30. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_infos.py +0 -0
  31. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_meshcore_ollama.py +0 -0
  32. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_msg.py +0 -0
  33. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_pingbot.py +0 -0
  34. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_repeater_status.py +0 -0
  35. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_repeater_telemetry.py +0 -0
  36. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_rss_bot.py +0 -0
  37. {meshcore-2.2.22 → meshcore-2.2.23}/examples/serial_trace.py +0 -0
  38. {meshcore-2.2.22 → meshcore-2.2.23}/examples/tcp_chat.py +0 -0
  39. {meshcore-2.2.22 → meshcore-2.2.23}/examples/tcp_login_status.py +0 -0
  40. {meshcore-2.2.22 → meshcore-2.2.23}/examples/tcp_mchome_contacts.py +0 -0
  41. {meshcore-2.2.22 → meshcore-2.2.23}/examples/tcp_mchome_infos.py +0 -0
  42. {meshcore-2.2.22 → meshcore-2.2.23}/examples/tcp_mchome_msg.py +0 -0
  43. {meshcore-2.2.22 → meshcore-2.2.23}/examples/tcp_mchome_readmsgs.py +0 -0
  44. {meshcore-2.2.22 → meshcore-2.2.23}/pytest.ini +0 -0
  45. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/__init__.py +0 -0
  46. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/ble_cx.py +0 -0
  47. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/commands/__init__.py +0 -0
  48. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/commands/base.py +0 -0
  49. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/commands/binary.py +0 -0
  50. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/commands/control_data.py +0 -0
  51. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/commands/device.py +0 -0
  52. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/commands/messaging.py +0 -0
  53. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/connection_manager.py +0 -0
  54. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/events.py +0 -0
  55. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/lpp_json_encoder.py +0 -0
  56. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/meshcore.py +0 -0
  57. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/packets.py +0 -0
  58. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/parsing.py +0 -0
  59. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/serial_cx.py +0 -0
  60. {meshcore-2.2.22 → meshcore-2.2.23}/src/meshcore/tcp_cx.py +0 -0
  61. {meshcore-2.2.22 → meshcore-2.2.23}/tests/README.md +0 -0
  62. {meshcore-2.2.22 → meshcore-2.2.23}/tests/test_ble_connection.py +0 -0
  63. {meshcore-2.2.22 → meshcore-2.2.23}/tests/test_ble_pin_pairing.py +0 -0
  64. {meshcore-2.2.22 → meshcore-2.2.23}/tests/test_meshcore_ble_pin.py +0 -0
  65. {meshcore-2.2.22 → meshcore-2.2.23}/tests/unit/test_commands.py +0 -0
  66. {meshcore-2.2.22 → meshcore-2.2.23}/tests/unit/test_events.py +0 -0
  67. {meshcore-2.2.22 → meshcore-2.2.23}/tests/unit/test_private_key_export.py +0 -0
  68. {meshcore-2.2.22 → meshcore-2.2.23}/tests/unit/test_reader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcore
3
- Version: 2.2.22
3
+ Version: 2.2.23
4
4
  Summary: Base classes for communicating with meshcore companion radios
5
5
  Project-URL: Homepage, https://github.com/fdlamotte/meshcore_py
6
6
  Project-URL: Issues, https://github.com/fdlamotte/meshcore_py/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "meshcore"
7
- version = "2.2.22"
7
+ version = "2.2.23"
8
8
  authors = [
9
9
  { name="Florent de Lamotte", email="florent@frizoncorrea.fr" },
10
10
  { name="Alex Wolden", email="awolden@gmail.com" },
@@ -105,24 +105,46 @@ class ContactCommands(CommandHandlerBase):
105
105
  data = b"\x0f" + key_bytes
106
106
  return await self.send(data, [EventType.OK, EventType.ERROR])
107
107
 
108
- async def update_contact(self, contact, path=None, flags=None) -> Event:
108
+ async def update_contact(self, contact, path=None, flags=None, path_hash_mode=None) -> Event:
109
109
  if path is None:
110
110
  out_path_hex = contact["out_path"]
111
111
  out_path_len = contact["out_path_len"]
112
+ out_path_hash_mode = contact["out_path_hash_mode"]
112
113
  else:
113
- path_hash_size = 1
114
- res = await self.send_device_query()
115
- if not res is None and res.type != EventType.ERROR:
116
- if "path_hash_mode" in res.payload:
117
- path_hash_size = res.payload["path_hash_mode"] + 1
114
+ if path_hash_mode is None: # not specified when calling func
115
+ if ":" in path: # mode specified in path string
116
+ path_hash_mode = int(path.split(":")[1])
117
+ path = path.split(":")[0].replace(":","")
118
+ else: # use device one by default
119
+ path_hash_mode = contact["out_path_len"] >> 6 # would fallback to previous val
120
+ res = await self.send_device_query()
121
+ if not res is None and res.type != EventType.ERROR:
122
+ if "path_hash_mode" in res.payload:
123
+ path_hash_size = res.payload["path_hash_mode"] + 1
124
+ else:
125
+ if ":" in path: # remove as it has been specified in args
126
+ path = path.split(":")[0].replace(":","")
127
+
128
+ path_hash_size = path_hash_mode + 1
129
+
130
+ print(path_hash_size)
118
131
 
119
132
  out_path_hex = path
120
133
  out_path_len = int(len(path) / (2 * path_hash_size))
134
+ out_path_hash_mode = path_hash_mode
135
+
136
+ print(f"Setting {contact["adv_name"]} path to {out_path_hex} with mode {out_path_hash_mode}")
121
137
 
122
138
  # reflect the change
139
+ contact["out_path_hash_mode"] = path_hash_mode
123
140
  contact["out_path"] = out_path_hex
124
141
  contact["out_path_len"] = out_path_len
142
+
125
143
  out_path_hex = out_path_hex + (128 - len(out_path_hex)) * "0"
144
+ if out_path_len == -1: # path did not change and contact was flood
145
+ out_path_len = 255 # we are signed
146
+ else:
147
+ out_path_len = out_path_len | (path_hash_mode << 6)
126
148
 
127
149
  if flags is None:
128
150
  flags = contact["flags"]
@@ -137,7 +159,7 @@ class ContactCommands(CommandHandlerBase):
137
159
  + bytes.fromhex(contact["public_key"])
138
160
  + contact["type"].to_bytes(1, "little")
139
161
  + flags.to_bytes(1, "little")
140
- + out_path_len.to_bytes(1, "little", signed=True)
162
+ + int(out_path_len).to_bytes(1, "little", signed=False)
141
163
  + bytes.fromhex(out_path_hex)
142
164
  + bytes.fromhex(adv_name_hex)
143
165
  + contact["last_advert"].to_bytes(4, "little")
@@ -149,8 +171,8 @@ class ContactCommands(CommandHandlerBase):
149
171
  async def add_contact(self, contact) -> Event:
150
172
  return await self.update_contact(contact)
151
173
 
152
- async def change_contact_path(self, contact, path) -> Event:
153
- return await self.update_contact(contact, path)
174
+ async def change_contact_path(self, contact, path, path_hash_mode=None) -> Event:
175
+ return await self.update_contact(contact, path, path_hash_mode)
154
176
 
155
177
  async def change_contact_flags(self, contact, flags) -> Event:
156
178
  return await self.update_contact(contact, flags=flags)
@@ -162,4 +184,3 @@ class ContactCommands(CommandHandlerBase):
162
184
  async def get_autoadd_config(self) -> Event:
163
185
  data = b"\x3B"
164
186
  return await self.send(data, [EventType.AUTOADD_CONFIG, EventType.ERROR])
165
-
@@ -99,7 +99,13 @@ class MessageReader:
99
99
  c["public_key"] = dbuf.read(32).hex()
100
100
  c["type"] = dbuf.read(1)[0]
101
101
  c["flags"] = dbuf.read(1)[0]
102
- c["out_path_len"] = int.from_bytes(dbuf.read(1), signed=True, byteorder="little")
102
+ plen = int.from_bytes(dbuf.read(1), signed=False, byteorder="little")
103
+ if plen == 255: # flood
104
+ c["out_path_hash_mode"] = -1
105
+ c["out_path_len"] = -1 # 6 LSB
106
+ else:
107
+ c["out_path_hash_mode"] = plen >> 6
108
+ c["out_path_len"] = plen & 0x3F # 6 LSB
103
109
  c["out_path"] = dbuf.read(64).replace(b"\0", b"").hex()
104
110
  c["adv_name"] = dbuf.read(32).decode("utf-8", "ignore").replace("\0", "")
105
111
  c["last_advert"] = int.from_bytes(dbuf.read(4), byteorder="little")
@@ -173,7 +179,13 @@ class MessageReader:
173
179
  res = {}
174
180
  res["type"] = "PRIV"
175
181
  res["pubkey_prefix"] = dbuf.read(6).hex()
176
- res["path_len"] = dbuf.read(1)[0]
182
+ plen = dbuf.read(1)[0]
183
+ if plen == 255 : # direct message
184
+ res["path_hash_mode"] = -1
185
+ res["path_len"] = plen
186
+ else:
187
+ res["path_hash_mode"] = plen >> 6
188
+ res["path_len"] = plen & 0x3F
177
189
  txt_type = dbuf.read(1)[0]
178
190
  res["txt_type"] = txt_type
179
191
  res["sender_timestamp"] = int.from_bytes(dbuf.read(4), byteorder="little")
@@ -196,7 +208,13 @@ class MessageReader:
196
208
  res["SNR"] = int.from_bytes(dbuf.read(1), byteorder="little", signed=True) / 4
197
209
  dbuf.read(2) # reserved
198
210
  res["pubkey_prefix"] = dbuf.read(6).hex()
199
- res["path_len"] = dbuf.read(1)[0]
211
+ plen = dbuf.read(1)[0]
212
+ if plen == 255 : # direct message
213
+ res["path_hash_mode"] = -1
214
+ res["path_len"] = plen
215
+ else:
216
+ res["path_hash_mode"] = plen >> 6
217
+ res["path_len"] = plen & 0x3F
200
218
  txt_type = dbuf.read(1)[0]
201
219
  res["txt_type"] = txt_type
202
220
  res["sender_timestamp"] = int.from_bytes(dbuf.read(4), byteorder="little")
@@ -217,7 +235,13 @@ class MessageReader:
217
235
  res = {}
218
236
  res["type"] = "CHAN"
219
237
  res["channel_idx"] = dbuf.read(1)[0]
220
- res["path_len"] = dbuf.read(1)[0]
238
+ plen = dbuf.read(1)[0]
239
+ if plen == 255 : # direct message
240
+ res["path_hash_mode"] = -1
241
+ res["path_len"] = plen
242
+ else:
243
+ res["path_hash_mode"] = plen >> 6
244
+ res["path_len"] = plen & 0x3F
221
245
  res["txt_type"] = dbuf.read(1)[0]
222
246
  res["sender_timestamp"] = int.from_bytes(dbuf.read(4), byteorder="little", signed=False)
223
247
  text = dbuf.read().strip(b"\0")
@@ -249,7 +273,13 @@ class MessageReader:
249
273
  res["SNR"] = int.from_bytes(dbuf.read(1), byteorder="little", signed=True) / 4
250
274
  dbuf.read(2) # reserved
251
275
  res["channel_idx"] = dbuf.read(1)[0]
252
- res["path_len"] = dbuf.read(1)[0]
276
+ plen = dbuf.read(1)[0]
277
+ if plen == 255 : # direct message
278
+ res["path_hash_mode"] = -1
279
+ res["path_len"] = plen
280
+ else:
281
+ res["path_hash_mode"] = plen >> 6
282
+ res["path_len"] = plen & 0x3F
253
283
  res["txt_type"] = dbuf.read(1)[0]
254
284
  res["sender_timestamp"] = int.from_bytes(dbuf.read(4), byteorder="little", signed=False)
255
285
  text = dbuf.read()
File without changes
File without changes
File without changes
File without changes
File without changes