blob: 89329c0cebb81a32e4905e4265907d1a8b57ab59 [file] [log] [blame]
#
# Copyright (c) 2021 Project CHIP Authors
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import argparse
import atexit
import builtins
import logging
import os
import pathlib
import coloredlogs
from rich import inspect, pretty
from rich.console import Console
import matter.CertificateAuthority
import matter.clusters as Clusters # noqa: F401
import matter.FabricAdmin
import matter.logging
import matter.native
from matter.ChipStack import ChipStack
from matter.storage import PersistentStorageINI, PersistentStorageJSON
def ReplInit(debug):
#
# Install the pretty printer that rich provides to replace the existing
# printer.
#
pretty.install(indent_guides=True, expand_all=True)
console = Console()
console.rule('Matter REPL')
console.print('''
Welcome to the Matter Python REPL!
For help, please type [bold green]matterhelp()[/]
To get more information on a particular object/class, you can pass
that into [bold green]matterhelp()[/] as well.
''')
console.rule()
coloredlogs.install(level='DEBUG')
matter.logging.RedirectToPythonLogging()
if debug:
logging.getLogger().setLevel(logging.DEBUG)
else:
logging.getLogger().setLevel(logging.WARN)
certificateAuthorityManager = None
@atexit.register
def StackShutdown():
if not certificateAuthorityManager:
return
certificateAuthorityManager.Shutdown()
builtins.chipStack.Shutdown()
def matterhelp(classOrObj=None):
if (classOrObj is None):
inspect(builtins.devCtrl, methods=True, help=True, private=False)
inspect(mattersetlog)
inspect(mattersetdebug)
else:
inspect(classOrObj, methods=True, help=True, private=False)
def mattersetlog(level):
logging.getLogger().setLevel(level)
def mattersetdebug(enableDebugMode: bool = True):
''' Enables debug mode that is utilized by some Matter modules
to better facilitate debugging of failures (e.g throwing exceptions instead
of returning well-formatted results).
'''
builtins.enableDebugMode = enableDebugMode
def main():
console = Console()
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
"-d", "--debug", help="set default logging level to debug", action="store_true")
parser.add_argument(
"-s", "--storage-path", metavar="PATH", default="/tmp/repl-storage.json",
help="path to persistent storage configuration file")
parser.add_argument(
"--chip-tool-common-storage-path", metavar="PATH",
help="path to chip-tool common persistent storage configuration file (INI format)")
parser.add_argument(
"--chip-tool-fabric-storage-path", metavar="PATH",
help="path to chip-tool fabric persistent storage configuration file (INI format)")
parser.add_argument(
"-t", "--trust-store", metavar="PATH", default="credentials/development/paa-root-certs",
help="path to the PAA trust store")
parser.add_argument(
"-b", "--ble-controller", metavar="INDEX", type=int, default=0,
help="BLE controller selector (see example or platform docs for details)")
parser.add_argument(
"-i", "--server-interactions", action="store_true",
help="enable server interactions")
args = parser.parse_args()
if args.chip_tool_common_storage_path or args.chip_tool_fabric_storage_path:
if not (args.chip_tool_common_storage_path and args.chip_tool_fabric_storage_path):
console.print('''
[bold red]Error: [/][bold]One must specify both chip-tool common and chip-tool fabric storage paths[/]
''')
return
if not os.path.exists(args.trust_store):
# there is a chance that the script is being run from a sub-path of a checkout.
# try to adjust for convenience
store_path = pathlib.Path(args.trust_store)
if not store_path.is_absolute():
prefix = pathlib.Path().absolute()
while prefix != prefix.parent:
if prefix.joinpath(store_path).exists():
oldpath = args.trust_store
args.trust_store = prefix.joinpath(store_path).as_posix()
console.print(f'''
[bold] Replacing [/] store path {oldpath} with {args.trust_store}
Note that you are still running from {os.getcwd()} so other relative paths may be off.
''')
break
prefix = prefix.parent
if not os.path.exists(args.trust_store):
console.print(f'''
[bold red] Missing directory: [/]{args.trust_store}
[bold] Your current directory: [/]{os.getcwd()}
Please add a valid `--trust-store` argument to your script. If using jupyterlab,
the command should look like:
%run {{module.path}} --trust-store <path_to_sdk_root>/credentials/development/paa-root-certs
or run `os.chdir` to the root of your Matter SDK repository checkout.
''')
# nothing we can do ... things will NOT work
return
matter.native.Init(bluetoothAdapter=args.ble_controller)
global certificateAuthorityManager
global chipStack
global caList
global devCtrl
ReplInit(args.debug)
if args.chip_tool_common_storage_path and args.chip_tool_fabric_storage_path:
storage = PersistentStorageINI(args.chip_tool_common_storage_path, args.chip_tool_fabric_storage_path)
else:
storage = PersistentStorageJSON(args.storage_path)
chipStack = ChipStack(storage, enableServerInteractions=args.server_interactions)
certificateAuthorityManager = matter.CertificateAuthority.CertificateAuthorityManager(chipStack, chipStack.GetStorageManager())
certificateAuthorityManager.LoadAuthoritiesFromStorage()
if not certificateAuthorityManager.activeCaList:
ca = certificateAuthorityManager.NewCertificateAuthority()
ca.NewFabricAdmin(vendorId=0xFFF1, fabricId=1)
elif not certificateAuthorityManager.activeCaList[0].adminList:
certificateAuthorityManager.activeCaList[0].NewFabricAdmin(vendorId=0xFFF1, fabricId=1)
caList = certificateAuthorityManager.activeCaList
devCtrl = caList[0].adminList[0].NewController(paaTrustStorePath=args.trust_store)
builtins.devCtrl = devCtrl
console.print(f'''
The following objects have been created:\n
\t[bold green]certificateAuthorityManager[/]:\tManages a list of CertificateAuthority instances
\t[bold green]caList[/]:\t\t\t\tThe list of CertificateAuthority instances
\t[bold green]caList\\[n].adminList\\[m][/]:\t\tA specific FabricAdmin object at index m for the nth CertificateAuthority instance
\t[bold green]devCtrl[/]:\t\t\tDefault Matter Device Controller (nodeId=0x{devCtrl.nodeId:016X}) to manage [bold green]caList[0].adminList[0][/] (fabricId={caList[0].adminList[0].fabricId})
''')
if __name__ == "__main__":
main()