libosdp 3.0.5__tar.gz → 3.0.7__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.
- {libosdp-3.0.5 → libosdp-3.0.7}/PKG-INFO +1 -1
- {libosdp-3.0.5 → libosdp-3.0.7}/libosdp.egg-info/PKG-INFO +1 -1
- {libosdp-3.0.5 → libosdp-3.0.7}/libosdp.egg-info/SOURCES.txt +2 -2
- {libosdp-3.0.5 → libosdp-3.0.7}/osdp/__init__.py +3 -3
- {libosdp-3.0.5 → libosdp-3.0.7}/osdp/constants.py +9 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/osdp/control_panel.py +32 -7
- {libosdp-3.0.5 → libosdp-3.0.7}/osdp/key_store.py +8 -6
- {libosdp-3.0.5 → libosdp-3.0.7}/osdp/peripheral_device.py +1 -1
- {libosdp-3.0.5 → libosdp-3.0.7}/setup.py +7 -6
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/include/osdp.h +84 -6
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/python/osdp_sys/cp.c +57 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/python/osdp_sys/data.c +63 -3
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/python/osdp_sys/module.c +10 -1
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/python/osdp_sys/module.h +1 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_common.c +9 -4
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_common.h +83 -6
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_config.h +7 -5
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_cp.c +176 -96
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_file.c +160 -61
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_file.h +7 -3
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_pd.c +36 -39
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_phy.c +39 -28
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_sc.c +4 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/include/utils/utils.h +9 -6
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/src/logger.c +21 -25
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/src/utils.c +29 -2
- {libosdp-3.0.5 → libosdp-3.0.7}/MANIFEST.in +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/README.md +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/libosdp.egg-info/dependency_links.txt +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/libosdp.egg-info/top_level.txt +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/osdp/channel.py +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/osdp/helpers.py +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/pyproject.toml +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/setup.cfg +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/python/osdp_sys/base.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/python/osdp_sys/pd.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/python/osdp_sys/utils.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/crypto/tinyaes.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/crypto/tinyaes_src.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/crypto/tinyaes_src.h +0 -0
- /libosdp-3.0.5/vendor/src/osdp_pcap.c → /libosdp-3.0.7/vendor/src/osdp_diag.c +0 -0
- /libosdp-3.0.5/vendor/src/osdp_pcap.h → /libosdp-3.0.7/vendor/src/osdp_diag.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/src/osdp_export.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/include/utils/assert.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/include/utils/disjoint_set.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/include/utils/list.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/include/utils/logger.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/include/utils/pcap_gen.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/include/utils/queue.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/include/utils/slab.h +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/src/disjoint_set.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/src/list.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/src/pcap_gen.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/src/queue.c +0 -0
- {libosdp-3.0.5 → libosdp-3.0.7}/vendor/utils/src/slab.c +0 -0
|
@@ -25,11 +25,11 @@ vendor/src/osdp_common.c
|
|
|
25
25
|
vendor/src/osdp_common.h
|
|
26
26
|
vendor/src/osdp_config.h
|
|
27
27
|
vendor/src/osdp_cp.c
|
|
28
|
+
vendor/src/osdp_diag.c
|
|
29
|
+
vendor/src/osdp_diag.h
|
|
28
30
|
vendor/src/osdp_export.h
|
|
29
31
|
vendor/src/osdp_file.c
|
|
30
32
|
vendor/src/osdp_file.h
|
|
31
|
-
vendor/src/osdp_pcap.c
|
|
32
|
-
vendor/src/osdp_pcap.h
|
|
33
33
|
vendor/src/osdp_pd.c
|
|
34
34
|
vendor/src/osdp_phy.c
|
|
35
35
|
vendor/src/osdp_sc.c
|
|
@@ -8,10 +8,10 @@ from .control_panel import ControlPanel
|
|
|
8
8
|
from .peripheral_device import PeripheralDevice
|
|
9
9
|
from .key_store import KeyStore
|
|
10
10
|
from .constants import (
|
|
11
|
-
LibFlag, Command, CommandLEDColor, CommandFileTxFlags,
|
|
12
|
-
|
|
11
|
+
LibFlag, Command, CommandLEDColor, CommandFileTxFlags, Event, EventNotification,
|
|
12
|
+
CardFormat, Capability, LogLevel, StatusReportType
|
|
13
13
|
)
|
|
14
|
-
from .helpers import PDInfo, PDCapabilities
|
|
14
|
+
from .helpers import PdId, PDInfo, PDCapabilities
|
|
15
15
|
from .channel import Channel
|
|
16
16
|
|
|
17
17
|
__author__ = 'Siddharth Chandrasekaran <sidcha.dev@gmail.com>'
|
|
@@ -10,6 +10,9 @@ class LibFlag:
|
|
|
10
10
|
EnforceSecure = osdp_sys.FLAG_ENFORCE_SECURE
|
|
11
11
|
InstallMode = osdp_sys.FLAG_INSTALL_MODE
|
|
12
12
|
IgnoreUnsolicited = osdp_sys.FLAG_IGN_UNSOLICITED
|
|
13
|
+
EnableNotification = osdp_sys.FLAG_ENABLE_NOTIFICATION
|
|
14
|
+
CapturePackets = osdp_sys.FLAG_CAPTURE_PACKETS
|
|
15
|
+
AllowEmptyEncryptedDataBlock = osdp_sys.FLAG_ALLOW_EMPTY_ENCRYPTED_DATA_BLOCK
|
|
13
16
|
|
|
14
17
|
class LogLevel:
|
|
15
18
|
Emergency = osdp_sys.LOG_EMERG
|
|
@@ -51,11 +54,17 @@ class CommandLEDColor:
|
|
|
51
54
|
class CommandFileTxFlags:
|
|
52
55
|
Cancel = osdp_sys.CMD_FILE_TX_FLAG_CANCEL
|
|
53
56
|
|
|
57
|
+
class EventNotification:
|
|
58
|
+
Command = osdp_sys.EVENT_NOTIFICATION_COMMAND
|
|
59
|
+
SecureChannelStatus = osdp_sys.EVENT_NOTIFICATION_SC_STATUS
|
|
60
|
+
PeripheralDeviceStatus = osdp_sys.EVENT_NOTIFICATION_PD_STATUS
|
|
61
|
+
|
|
54
62
|
class Event:
|
|
55
63
|
CardRead = osdp_sys.EVENT_CARDREAD
|
|
56
64
|
KeyPress = osdp_sys.EVENT_KEYPRESS
|
|
57
65
|
ManufacturerReply = osdp_sys.EVENT_MFGREP
|
|
58
66
|
Status = osdp_sys.EVENT_STATUS
|
|
67
|
+
Notification = osdp_sys.EVENT_NOTIFICATION
|
|
59
68
|
|
|
60
69
|
class CardFormat:
|
|
61
70
|
Unspecified = osdp_sys.CARD_FMT_RAW_UNSPECIFIED
|
|
@@ -3,17 +3,14 @@
|
|
|
3
3
|
#
|
|
4
4
|
# SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
#
|
|
6
|
-
import sys
|
|
7
|
-
import os
|
|
8
|
-
import tempfile
|
|
9
6
|
import osdp_sys
|
|
10
7
|
import time
|
|
11
8
|
import queue
|
|
12
9
|
import threading
|
|
13
|
-
from typing import Callable
|
|
10
|
+
from typing import Callable, Tuple
|
|
14
11
|
|
|
15
|
-
from .helpers import PDInfo
|
|
16
|
-
from .constants import LibFlag, LogLevel
|
|
12
|
+
from .helpers import PDInfo, PdId
|
|
13
|
+
from .constants import Capability, LibFlag, LogLevel
|
|
17
14
|
|
|
18
15
|
class ControlPanel():
|
|
19
16
|
def __init__(
|
|
@@ -73,6 +70,29 @@ class ControlPanel():
|
|
|
73
70
|
pd = self.pd_addr.index(address)
|
|
74
71
|
return bool(self.status() & (1 << pd))
|
|
75
72
|
|
|
73
|
+
def get_pd_id(self, address: int) -> PdId:
|
|
74
|
+
pd = self.pd_addr.index(address)
|
|
75
|
+
self.lock.acquire()
|
|
76
|
+
pd_id_dict = self.ctx.get_pd_id(pd)
|
|
77
|
+
self.lock.release()
|
|
78
|
+
if pd_id_dict:
|
|
79
|
+
# version: int, model: int, vendor_code: int, serial_number: int, firmware_version: int
|
|
80
|
+
pd_id = PdId(
|
|
81
|
+
pd_id_dict['version'],
|
|
82
|
+
pd_id_dict['model'],
|
|
83
|
+
pd_id_dict['vendor_code'],
|
|
84
|
+
pd_id_dict['serial_number'],
|
|
85
|
+
pd_id_dict['firmware_version']
|
|
86
|
+
)
|
|
87
|
+
return pd_id
|
|
88
|
+
|
|
89
|
+
def check_capability(self, address: int, cap: Capability) -> Tuple[int, int]:
|
|
90
|
+
pd = self.pd_addr.index(address)
|
|
91
|
+
self.lock.acquire()
|
|
92
|
+
compliance_level, num_items = self.ctx.check_capability(pd, cap)
|
|
93
|
+
self.lock.release()
|
|
94
|
+
return (compliance_level, num_items)
|
|
95
|
+
|
|
76
96
|
def get_num_online(self):
|
|
77
97
|
online = 0
|
|
78
98
|
bitmask = self.status()
|
|
@@ -164,7 +184,7 @@ class ControlPanel():
|
|
|
164
184
|
count += 1
|
|
165
185
|
return res
|
|
166
186
|
|
|
167
|
-
def online_wait(self, address, timeout=
|
|
187
|
+
def online_wait(self, address, timeout=8):
|
|
168
188
|
count = 0
|
|
169
189
|
res = False
|
|
170
190
|
while count < timeout * 2:
|
|
@@ -175,6 +195,11 @@ class ControlPanel():
|
|
|
175
195
|
count += 1
|
|
176
196
|
return res
|
|
177
197
|
|
|
198
|
+
def offline_wait(self, address, timeout=8):
|
|
199
|
+
count = 0
|
|
200
|
+
time.sleep(timeout)
|
|
201
|
+
return self.is_online(address) == False
|
|
202
|
+
|
|
178
203
|
def sc_wait(self, address, timeout=5):
|
|
179
204
|
count = 0
|
|
180
205
|
res = False
|
|
@@ -28,11 +28,8 @@ class KeyStore():
|
|
|
28
28
|
key.append(random.randint(0, 255))
|
|
29
29
|
return bytes(key)
|
|
30
30
|
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
raise RuntimeError
|
|
34
|
-
key = self.keys[name]
|
|
35
|
-
with open(self.key_file(name), "w") as f:
|
|
31
|
+
def _store_key(self, key):
|
|
32
|
+
with open(self.key_file(key), "w") as f:
|
|
36
33
|
f.write(key.hex())
|
|
37
34
|
|
|
38
35
|
def get_key(self, name):
|
|
@@ -46,6 +43,11 @@ class KeyStore():
|
|
|
46
43
|
self.keys[name] = self.gen_key(key_len)
|
|
47
44
|
return self.keys[name]
|
|
48
45
|
|
|
46
|
+
def commit_key(self, name):
|
|
47
|
+
if name not in self.keys:
|
|
48
|
+
raise RuntimeError
|
|
49
|
+
self._store_key(self.keys[name])
|
|
50
|
+
|
|
49
51
|
def update_key(self, name, key):
|
|
50
52
|
if name not in self.keys:
|
|
51
53
|
raise RuntimeError
|
|
@@ -63,4 +65,4 @@ class KeyStore():
|
|
|
63
65
|
|
|
64
66
|
def __del__(self):
|
|
65
67
|
if self.temp_dir:
|
|
66
|
-
self.temp_dir.cleanup()
|
|
68
|
+
self.temp_dir.cleanup()
|
|
@@ -11,7 +11,7 @@ import shutil
|
|
|
11
11
|
import subprocess
|
|
12
12
|
|
|
13
13
|
project_name = "libosdp"
|
|
14
|
-
project_version = "3.0.
|
|
14
|
+
project_version = "3.0.7"
|
|
15
15
|
current_dir = os.path.dirname(os.path.realpath(__file__))
|
|
16
16
|
repo_root = os.path.realpath(os.path.join(current_dir, ".."))
|
|
17
17
|
|
|
@@ -132,8 +132,8 @@ other_files = [
|
|
|
132
132
|
"src/osdp_config.h.in",
|
|
133
133
|
|
|
134
134
|
# Optional when PACKET_TRACE is enabled
|
|
135
|
-
"src/
|
|
136
|
-
"src/
|
|
135
|
+
"src/osdp_diag.c",
|
|
136
|
+
"src/osdp_diag.h",
|
|
137
137
|
"utils/include/utils/pcap_gen.h",
|
|
138
138
|
"utils/src/pcap_gen.c",
|
|
139
139
|
]
|
|
@@ -147,14 +147,15 @@ try_vendor_sources(
|
|
|
147
147
|
)
|
|
148
148
|
|
|
149
149
|
definitions = [
|
|
150
|
-
|
|
150
|
+
"CONFIG_OSDP_PACKET_TRACE",
|
|
151
151
|
# "CONFIG_OSDP_DATA_TRACE",
|
|
152
152
|
# "CONFIG_OSDP_SKIP_MARK_BYTE",
|
|
153
153
|
]
|
|
154
154
|
|
|
155
|
-
if "CONFIG_OSDP_PACKET_TRACE" in definitions
|
|
155
|
+
if ("CONFIG_OSDP_PACKET_TRACE" in definitions or
|
|
156
|
+
"CONFIG_OSDP_DATA_TRACE" in definitions):
|
|
156
157
|
source_files += [
|
|
157
|
-
"src/
|
|
158
|
+
"src/osdp_diag.c",
|
|
158
159
|
"utils/src/pcap_gen.c",
|
|
159
160
|
]
|
|
160
161
|
|
|
@@ -52,6 +52,37 @@ extern "C" {
|
|
|
52
52
|
*/
|
|
53
53
|
#define OSDP_FLAG_IGN_UNSOLICITED 0x00040000
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* @brief Enable LibOSDP notification events - @ref osdp_event_notification - to
|
|
57
|
+
* be reported using the event callback method registered by the application.
|
|
58
|
+
*
|
|
59
|
+
* @note These events, unlike others, are not generated by the PD.
|
|
60
|
+
*
|
|
61
|
+
* @note This is a CP mode only flag; in PD mode this flag has no use.
|
|
62
|
+
*/
|
|
63
|
+
#define OSDP_FLAG_ENABLE_NOTIFICATION 0x00080000
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @brief Capture raw osdp packets as seen by this device to a pcap file.
|
|
67
|
+
* LibOSDP must be built with CONFIG_OSDP_PACKET_TRACE or CONFIG_OSDP_DATA_TRACE
|
|
68
|
+
* for this flag to be in effect.
|
|
69
|
+
*
|
|
70
|
+
* @note The app must call osdp_{cp,pd}_teardown() before existing for the
|
|
71
|
+
* capture file to be finalized and written to the disk.
|
|
72
|
+
*/
|
|
73
|
+
#define OSDP_FLAG_CAPTURE_PACKETS 0x00100000
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @brief Allow an empty encrypted data block(SCS_17 and SCS_18 packets).
|
|
77
|
+
* This is non-conforming to the standard. If there is no data to be
|
|
78
|
+
* transferred, the CP should instead use the SCS_15/SCS_16 messages.
|
|
79
|
+
* Some OSDP implementations are buggy and send a 0-length data block with
|
|
80
|
+
* the SCS_17 and SCS_18 messages, this flag accepts that buggy behavior.
|
|
81
|
+
*
|
|
82
|
+
* @note this is a PD mode only flag
|
|
83
|
+
*/
|
|
84
|
+
#define OSDP_FLAG_ALLOW_EMPTY_ENCRYPTED_DATA_BLOCK 0x00200000
|
|
85
|
+
|
|
55
86
|
/**
|
|
56
87
|
* @brief Various PD capability function codes.
|
|
57
88
|
*/
|
|
@@ -365,7 +396,7 @@ enum osdp_status_report_type {
|
|
|
365
396
|
/**
|
|
366
397
|
* @brief Status report structure. Used by OSDP_CMD_STATUS and
|
|
367
398
|
* OSDP_EVENT_STATUS. In case of command, it is used to send a query to the PD
|
|
368
|
-
* while in the case of events, the
|
|
399
|
+
* while in the case of events, the PD responds back with this structure.
|
|
369
400
|
*
|
|
370
401
|
* This can is used by the PD to indicate various status change reports. Upto a
|
|
371
402
|
* maximum of 32 statuses can be reported using this API.
|
|
@@ -651,8 +682,8 @@ enum osdp_cmd_e {
|
|
|
651
682
|
OSDP_CMD_KEYSET, /**< Encryption Key Set Command */
|
|
652
683
|
OSDP_CMD_COMSET, /**< PD communication configuration command */
|
|
653
684
|
OSDP_CMD_MFG, /**< Manufacturer specific command */
|
|
654
|
-
OSDP_CMD_FILE_TX, /**< File transfer
|
|
655
|
-
OSDP_CMD_STATUS, /**< Status report
|
|
685
|
+
OSDP_CMD_FILE_TX, /**< File transfer command */
|
|
686
|
+
OSDP_CMD_STATUS, /**< Status report command */
|
|
656
687
|
OSDP_CMD_SENTINEL /**< Max command value */
|
|
657
688
|
};
|
|
658
689
|
|
|
@@ -779,6 +810,49 @@ struct osdp_event_mfgrep {
|
|
|
779
810
|
uint8_t data[OSDP_EVENT_MFGREP_MAX_DATALEN];
|
|
780
811
|
};
|
|
781
812
|
|
|
813
|
+
/**
|
|
814
|
+
* @brief LibOSDP event notification type
|
|
815
|
+
*/
|
|
816
|
+
enum osdp_event_notification_type {
|
|
817
|
+
/**
|
|
818
|
+
* Application command outcome report.
|
|
819
|
+
*
|
|
820
|
+
* arg0: The command ID
|
|
821
|
+
* arg1: outcome -- 0: success; -1: failure;
|
|
822
|
+
*/
|
|
823
|
+
OSDP_EVENT_NOTIFICATION_COMMAND,
|
|
824
|
+
/**
|
|
825
|
+
* Secure Channel state change
|
|
826
|
+
*
|
|
827
|
+
* arg0: status -- 0: inactive; 1: active
|
|
828
|
+
* arg1: scbk type -- 0: scbk; 1: scbk-d
|
|
829
|
+
*/
|
|
830
|
+
OSDP_EVENT_NOTIFICATION_SC_STATUS,
|
|
831
|
+
/**
|
|
832
|
+
* PD state change
|
|
833
|
+
*
|
|
834
|
+
* arg0: status -- 0: offline; 1: online
|
|
835
|
+
*/
|
|
836
|
+
OSDP_EVENT_NOTIFICATION_PD_STATUS,
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* @brief LibOSDP event notification
|
|
841
|
+
*
|
|
842
|
+
* These are events generated by LibOSDP for the application to indicate various
|
|
843
|
+
* status such as external command outcomes, SC state change notifications, etc.
|
|
844
|
+
* The app can use these events to perform housekeeping activities as needed.
|
|
845
|
+
*
|
|
846
|
+
* Each notification event type can use the provided additional data members
|
|
847
|
+
* @a arg0, @a arg1, ... in custom ways. See @ref osdp_event_notification_type
|
|
848
|
+
* for documentation on how to use them.
|
|
849
|
+
*/
|
|
850
|
+
struct osdp_event_notification {
|
|
851
|
+
enum osdp_event_notification_type type; /**< Notification type */
|
|
852
|
+
int arg0; /**< Additional data member */
|
|
853
|
+
int arg1; /**< Additional data member */
|
|
854
|
+
};
|
|
855
|
+
|
|
782
856
|
/**
|
|
783
857
|
* @brief OSDP PD Events
|
|
784
858
|
*/
|
|
@@ -787,6 +861,7 @@ enum osdp_event_type {
|
|
|
787
861
|
OSDP_EVENT_KEYPRESS, /**< Keypad press event */
|
|
788
862
|
OSDP_EVENT_MFGREP, /**< Manufacturer specific reply event */
|
|
789
863
|
OSDP_EVENT_STATUS, /**< Status event */
|
|
864
|
+
OSDP_EVENT_NOTIFICATION, /**< LibOSDP notification event */
|
|
790
865
|
OSDP_EVENT_SENTINEL /**< Max event value */
|
|
791
866
|
};
|
|
792
867
|
|
|
@@ -802,8 +877,9 @@ struct osdp_event {
|
|
|
802
877
|
union {
|
|
803
878
|
struct osdp_event_keypress keypress; /**< Keypress event structure */
|
|
804
879
|
struct osdp_event_cardread cardread; /**< Card read event structure */
|
|
805
|
-
struct osdp_event_mfgrep mfgrep; /**< Manufacturer
|
|
806
|
-
struct osdp_status_report status; /**< Status report event
|
|
880
|
+
struct osdp_event_mfgrep mfgrep; /**< Manufacturer specific response event struture */
|
|
881
|
+
struct osdp_status_report status; /**< Status report event structure */
|
|
882
|
+
struct osdp_event_notification notif;/**< Notification event structure */
|
|
807
883
|
};
|
|
808
884
|
};
|
|
809
885
|
|
|
@@ -1167,7 +1243,9 @@ void osdp_get_sc_status_mask(const osdp_t *ctx, uint8_t *bitmask);
|
|
|
1167
1243
|
* @param arg Opaque pointer that was provided in @ref osdp_file_ops when the
|
|
1168
1244
|
* ops struct was registered.
|
|
1169
1245
|
* @param file_id File ID of pre-agreed file between this CP and PD
|
|
1170
|
-
* @param size Size of the file that was opened (
|
|
1246
|
+
* @param size Size of the file that was opened (to be populated by sender). In
|
|
1247
|
+
* case of receiver, this value is just just input to indicate the incoming file
|
|
1248
|
+
* size.
|
|
1171
1249
|
*
|
|
1172
1250
|
* @retval 0 on success
|
|
1173
1251
|
* @retval -1 on errors
|
|
@@ -39,6 +39,9 @@ int pyosdp_cp_event_cb(void *data, int address, struct osdp_event *event)
|
|
|
39
39
|
pyosdp_cp_t *self = data;
|
|
40
40
|
PyObject *arglist, *result, *event_dict;
|
|
41
41
|
|
|
42
|
+
if (!self->event_cb)
|
|
43
|
+
return 0;
|
|
44
|
+
|
|
42
45
|
if (pyosdp_make_dict_event(&event_dict, event))
|
|
43
46
|
return -1;
|
|
44
47
|
|
|
@@ -86,6 +89,56 @@ static PyObject *pyosdp_cp_refresh(pyosdp_cp_t *self, pyosdp_cp_t *args)
|
|
|
86
89
|
Py_RETURN_NONE;
|
|
87
90
|
}
|
|
88
91
|
|
|
92
|
+
#define pyosdp_cp_get_pd_id_doc \
|
|
93
|
+
"Get PD_ID info as reported by the PD\n" \
|
|
94
|
+
"\n" \
|
|
95
|
+
"@param pd PD offset number\n" \
|
|
96
|
+
"\n" \
|
|
97
|
+
"@return dict with PD_ID info\n"
|
|
98
|
+
static PyObject *pyosdp_cp_get_pd_id(pyosdp_cp_t *self, PyObject *args)
|
|
99
|
+
{
|
|
100
|
+
int pd;
|
|
101
|
+
struct osdp_pd_id pd_id = {0};
|
|
102
|
+
|
|
103
|
+
if (!PyArg_ParseTuple(args, "I", &pd)) {
|
|
104
|
+
PyErr_SetString(PyExc_ValueError, "Invalid arguments");
|
|
105
|
+
Py_RETURN_NONE;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (osdp_cp_get_pd_id(self->ctx, pd, &pd_id)) {
|
|
109
|
+
PyErr_SetString(PyExc_ValueError, "invalid PD offset");
|
|
110
|
+
Py_RETURN_NONE;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return pyosdp_make_dict_pd_id(&pd_id);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#define pyosdp_cp_check_capability_doc \
|
|
117
|
+
"Get capability associated to a function_code as reported by the PD\n" \
|
|
118
|
+
"\n" \
|
|
119
|
+
"@param pd PD offset number\n" \
|
|
120
|
+
"@param capability function code\n" \
|
|
121
|
+
"\n" \
|
|
122
|
+
"@return (compliance_level, num_items)\n"
|
|
123
|
+
static PyObject *pyosdp_cp_check_capability(pyosdp_cp_t *self, PyObject *args)
|
|
124
|
+
{
|
|
125
|
+
int pd, function_code;
|
|
126
|
+
struct osdp_pd_cap cap = {0};
|
|
127
|
+
|
|
128
|
+
if (!PyArg_ParseTuple(args, "II", &pd, &function_code)) {
|
|
129
|
+
PyErr_SetString(PyExc_ValueError, "Invalid arguments");
|
|
130
|
+
Py_RETURN_NONE;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
cap.function_code = function_code;
|
|
134
|
+
if (osdp_cp_get_capability(self->ctx, pd, &cap)) {
|
|
135
|
+
PyErr_SetString(PyExc_ValueError, "invalid PD offset or function code");
|
|
136
|
+
Py_RETURN_NONE;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return Py_BuildValue("(II)", cap.compliance_level, cap.num_items);
|
|
140
|
+
}
|
|
141
|
+
|
|
89
142
|
#define pyosdp_cp_send_command_doc \
|
|
90
143
|
"Send an OSDP command to a PD\n" \
|
|
91
144
|
"\n" \
|
|
@@ -327,6 +380,10 @@ static PyMethodDef pyosdp_cp_tp_methods[] = {
|
|
|
327
380
|
METH_NOARGS, pyosdp_cp_set_flag_doc },
|
|
328
381
|
{ "clear_flag", (PyCFunction)pyosdp_cp_clear_flag,
|
|
329
382
|
METH_NOARGS, pyosdp_cp_clear_flag_doc },
|
|
383
|
+
{ "get_pd_id", (PyCFunction)pyosdp_cp_get_pd_id,
|
|
384
|
+
METH_VARARGS, pyosdp_cp_get_pd_id_doc },
|
|
385
|
+
{ "check_capability", (PyCFunction)pyosdp_cp_check_capability,
|
|
386
|
+
METH_VARARGS, pyosdp_cp_check_capability_doc },
|
|
330
387
|
{ NULL, NULL, 0, NULL } /* Sentinel */
|
|
331
388
|
};
|
|
332
389
|
|
|
@@ -44,9 +44,13 @@ static int pyosdp_make_struct_cmd_output(struct osdp_cmd *p, PyObject *dict)
|
|
|
44
44
|
static int pyosdp_make_dict_cmd_led(PyObject *obj, struct osdp_cmd *cmd)
|
|
45
45
|
{
|
|
46
46
|
bool is_temporary = false;
|
|
47
|
+
bool cancel_temporary = false;
|
|
47
48
|
struct osdp_cmd_led_params *p = &cmd->led.permanent;
|
|
48
49
|
|
|
49
|
-
if (cmd->led.temporary.control_code
|
|
50
|
+
if (cmd->led.temporary.control_code == 1 &&
|
|
51
|
+
cmd->led.permanent.control_code != 0) {
|
|
52
|
+
cancel_temporary = true;
|
|
53
|
+
} else if (cmd->led.temporary.control_code) {
|
|
50
54
|
p = &cmd->led.temporary;
|
|
51
55
|
is_temporary = true;
|
|
52
56
|
}
|
|
@@ -66,8 +70,14 @@ static int pyosdp_make_dict_cmd_led(PyObject *obj, struct osdp_cmd *cmd)
|
|
|
66
70
|
return -1;
|
|
67
71
|
if (pyosdp_dict_add_int(obj, "off_count", p->off_count))
|
|
68
72
|
return -1;
|
|
69
|
-
if (is_temporary
|
|
70
|
-
|
|
73
|
+
if (is_temporary) {
|
|
74
|
+
if (pyosdp_dict_add_int(obj, "timer_count", p->timer_count))
|
|
75
|
+
return -1;
|
|
76
|
+
}
|
|
77
|
+
if (cancel_temporary) {
|
|
78
|
+
if (pyosdp_dict_add_bool(obj, "cancel_temporary", cancel_temporary))
|
|
79
|
+
return -1;
|
|
80
|
+
}
|
|
71
81
|
return 0;
|
|
72
82
|
}
|
|
73
83
|
|
|
@@ -543,6 +553,37 @@ static int pyosdp_make_struct_event_status(struct osdp_event *p, PyObject *dict)
|
|
|
543
553
|
return 0;
|
|
544
554
|
}
|
|
545
555
|
|
|
556
|
+
static int pyosdp_make_dict_event_notif(PyObject *obj, struct osdp_event *event)
|
|
557
|
+
{
|
|
558
|
+
if (pyosdp_dict_add_int(obj, "type", event->notif.type))
|
|
559
|
+
return -1;
|
|
560
|
+
if (pyosdp_dict_add_int(obj, "arg0", event->notif.arg0))
|
|
561
|
+
return -1;
|
|
562
|
+
if (pyosdp_dict_add_int(obj, "arg1", event->notif.arg1))
|
|
563
|
+
return -1;
|
|
564
|
+
return 0;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
static int pyosdp_make_struct_event_notif(struct osdp_event *p, PyObject *dict)
|
|
568
|
+
{
|
|
569
|
+
int type, arg0, arg1;
|
|
570
|
+
struct osdp_event_notification *ev = &p->notif;
|
|
571
|
+
|
|
572
|
+
if (pyosdp_dict_get_int(dict, "type", &type))
|
|
573
|
+
return -1;
|
|
574
|
+
|
|
575
|
+
if (pyosdp_dict_get_int(dict, "arg0", &arg0))
|
|
576
|
+
return -1;
|
|
577
|
+
|
|
578
|
+
if (pyosdp_dict_get_int(dict, "arg1", &arg1))
|
|
579
|
+
return -1;
|
|
580
|
+
|
|
581
|
+
ev->type = type;
|
|
582
|
+
ev->arg0 = arg0;
|
|
583
|
+
ev->arg1 = arg1;
|
|
584
|
+
return 0;
|
|
585
|
+
}
|
|
586
|
+
|
|
546
587
|
static struct {
|
|
547
588
|
int (*dict_to_struct)(struct osdp_cmd *, PyObject *);
|
|
548
589
|
int (*struct_to_dict)(PyObject *, struct osdp_cmd *);
|
|
@@ -605,6 +646,10 @@ static struct {
|
|
|
605
646
|
.struct_to_dict = pyosdp_make_dict_event_status,
|
|
606
647
|
.dict_to_struct = pyosdp_make_struct_event_status,
|
|
607
648
|
},
|
|
649
|
+
[OSDP_EVENT_NOTIFICATION] = {
|
|
650
|
+
.struct_to_dict = pyosdp_make_dict_event_notif,
|
|
651
|
+
.dict_to_struct = pyosdp_make_struct_event_notif,
|
|
652
|
+
},
|
|
608
653
|
};
|
|
609
654
|
|
|
610
655
|
/* --- Exposed Methods --- */
|
|
@@ -679,3 +724,18 @@ int pyosdp_make_dict_event(PyObject **dict, struct osdp_event *event)
|
|
|
679
724
|
*dict = obj;
|
|
680
725
|
return 0;
|
|
681
726
|
}
|
|
727
|
+
|
|
728
|
+
PyObject *pyosdp_make_dict_pd_id(struct osdp_pd_id *pd_id)
|
|
729
|
+
{
|
|
730
|
+
PyObject *obj = PyDict_New();
|
|
731
|
+
if (obj == NULL)
|
|
732
|
+
return NULL;
|
|
733
|
+
|
|
734
|
+
pyosdp_dict_add_int(obj, "version", pd_id->version);
|
|
735
|
+
pyosdp_dict_add_int(obj, "model", pd_id->model);
|
|
736
|
+
pyosdp_dict_add_int(obj, "vendor_code", pd_id->vendor_code);
|
|
737
|
+
pyosdp_dict_add_int(obj, "serial_number", pd_id->serial_number);
|
|
738
|
+
pyosdp_dict_add_int(obj, "firmware_version", pd_id->firmware_version);
|
|
739
|
+
|
|
740
|
+
return obj;
|
|
741
|
+
}
|
|
@@ -22,6 +22,9 @@ void pyosdp_add_module_constants(PyObject *module)
|
|
|
22
22
|
ADD_CONST("FLAG_ENFORCE_SECURE", OSDP_FLAG_ENFORCE_SECURE);
|
|
23
23
|
ADD_CONST("FLAG_INSTALL_MODE", OSDP_FLAG_INSTALL_MODE);
|
|
24
24
|
ADD_CONST("FLAG_IGN_UNSOLICITED", OSDP_FLAG_IGN_UNSOLICITED);
|
|
25
|
+
ADD_CONST("FLAG_ENABLE_NOTIFICATION", OSDP_FLAG_ENABLE_NOTIFICATION);
|
|
26
|
+
ADD_CONST("FLAG_CAPTURE_PACKETS", OSDP_FLAG_CAPTURE_PACKETS);
|
|
27
|
+
ADD_CONST("FLAG_ALLOW_EMPTY_ENCRYPTED_DATA_BLOCK", OSDP_FLAG_ALLOW_EMPTY_ENCRYPTED_DATA_BLOCK);
|
|
25
28
|
|
|
26
29
|
ADD_CONST("LOG_EMERG", OSDP_LOG_EMERG);
|
|
27
30
|
ADD_CONST("LOG_ALERT", OSDP_LOG_ALERT);
|
|
@@ -49,14 +52,20 @@ void pyosdp_add_module_constants(PyObject *module)
|
|
|
49
52
|
ADD_CONST("STATUS_REPORT_OUTPUT", OSDP_STATUS_REPORT_OUTPUT)
|
|
50
53
|
ADD_CONST("STATUS_REPORT_REMOTE", OSDP_STATUS_REPORT_REMOTE)
|
|
51
54
|
|
|
52
|
-
/* For `struct osdp_cmd_file_tx
|
|
55
|
+
/* For `struct osdp_cmd_file_tx::flags` */
|
|
53
56
|
ADD_CONST("CMD_FILE_TX_FLAG_CANCEL", OSDP_CMD_FILE_TX_FLAG_CANCEL);
|
|
54
57
|
|
|
58
|
+
/* For `struct osdp_event_notification::type` */
|
|
59
|
+
ADD_CONST("EVENT_NOTIFICATION_COMMAND", OSDP_EVENT_NOTIFICATION_COMMAND);
|
|
60
|
+
ADD_CONST("EVENT_NOTIFICATION_SC_STATUS", OSDP_EVENT_NOTIFICATION_SC_STATUS);
|
|
61
|
+
ADD_CONST("EVENT_NOTIFICATION_PD_STATUS", OSDP_EVENT_NOTIFICATION_PD_STATUS);
|
|
62
|
+
|
|
55
63
|
/* enum osdp_event_type */
|
|
56
64
|
ADD_CONST("EVENT_CARDREAD", OSDP_EVENT_CARDREAD);
|
|
57
65
|
ADD_CONST("EVENT_KEYPRESS", OSDP_EVENT_KEYPRESS);
|
|
58
66
|
ADD_CONST("EVENT_MFGREP", OSDP_EVENT_MFGREP);
|
|
59
67
|
ADD_CONST("EVENT_STATUS", OSDP_EVENT_STATUS);
|
|
68
|
+
ADD_CONST("EVENT_NOTIFICATION", OSDP_EVENT_NOTIFICATION);
|
|
60
69
|
|
|
61
70
|
/* enum osdp_led_color_e */
|
|
62
71
|
ADD_CONST("LED_COLOR_NONE", OSDP_LED_COLOR_NONE);
|
|
@@ -91,5 +91,6 @@ int pyosdp_make_struct_cmd(struct osdp_cmd *cmd, PyObject *dict);
|
|
|
91
91
|
int pyosdp_make_dict_cmd(PyObject **dict, struct osdp_cmd *cmd);
|
|
92
92
|
int pyosdp_make_dict_event(PyObject **dict, struct osdp_event *event);
|
|
93
93
|
int pyosdp_make_struct_event(struct osdp_event *event, PyObject *dict);
|
|
94
|
+
PyObject *pyosdp_make_dict_pd_id(struct osdp_pd_id *pd_id);
|
|
94
95
|
|
|
95
96
|
#endif /* _PYOSDP_H_ */
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
|
|
7
|
+
#ifndef _GNU_SOURCE
|
|
8
|
+
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
|
9
|
+
#endif
|
|
10
|
+
|
|
6
11
|
#include <stdarg.h>
|
|
7
12
|
#include <stdlib.h>
|
|
8
13
|
#ifndef CONFIG_DISABLE_PRETTY_LOGGING
|
|
@@ -27,7 +32,7 @@ uint16_t osdp_compute_crc16(const uint8_t *buf, size_t len)
|
|
|
27
32
|
return crc16_itu_t(0x1D0F, buf, len);
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
int64_t osdp_millis_now(void)
|
|
35
|
+
__weak int64_t osdp_millis_now(void)
|
|
31
36
|
{
|
|
32
37
|
return millis_now();
|
|
33
38
|
}
|
|
@@ -95,7 +100,7 @@ const char *osdp_reply_name(int reply_id)
|
|
|
95
100
|
[REPLY_RSTATR - REPLY_ACK] = "RSTATR",
|
|
96
101
|
[REPLY_RAW - REPLY_ACK] = "RAW",
|
|
97
102
|
[REPLY_FMT - REPLY_ACK] = "FMT",
|
|
98
|
-
[
|
|
103
|
+
[REPLY_KEYPAD - REPLY_ACK] = "KEYPAD",
|
|
99
104
|
[REPLY_COM - REPLY_ACK] = "COM",
|
|
100
105
|
[REPLY_BIOREADR - REPLY_ACK] = "BIOREADR",
|
|
101
106
|
[REPLY_BIOMATCHR - REPLY_ACK] = "BIOMATCHR",
|
|
@@ -218,9 +223,9 @@ const char *osdp_get_version()
|
|
|
218
223
|
OSDP_EXPORT
|
|
219
224
|
const char *osdp_get_source_info()
|
|
220
225
|
{
|
|
221
|
-
if (
|
|
226
|
+
if (strlen(GIT_TAG) > 0) {
|
|
222
227
|
return GIT_BRANCH " (" GIT_TAG ")";
|
|
223
|
-
} else if (
|
|
228
|
+
} else if (strlen(GIT_REV) > 0) {
|
|
224
229
|
return GIT_BRANCH " (" GIT_REV GIT_DIFF ")";
|
|
225
230
|
} else {
|
|
226
231
|
return GIT_BRANCH;
|