Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev - Support primary or alternate option to choose the file system #100

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def main():
)

parser.add_argument('--cli', action = 'store_true', help = 'Use a command prompt, allowing for interactive completion of commands.')
parser.add_argument('--efs-shell', action = 'store_true', help = 'Spawn an interactive shell to navigate within the embedded filesystem (EFS) of the baseband device.')
#parser.add_argument('--efs-shell', action = 'store_true', help = 'Spawn an interactive shell to navigate within the embedded filesystem (EFS) of the baseband device.')
parser.add_argument('--efs-shell', nargs='?', const='efs', default=False, choices=['efs', 'efs2'], help='Spawn an interactive shell to navigate within the embedded filesystem (EFS) of the baseband device. Optionally specify "primary" or "alternate" to choose the file system.')
parser.add_argument('-v', '--verbose', action = 'store_true', help = 'Add output for each received or sent Diag packet.')

input_mode = parser.add_argument_group(title = 'Input mode', description = 'Choose an one least input mode for DIAG data.')
Expand Down Expand Up @@ -174,13 +175,13 @@ def parse_modules_args(args):
diag_input.add_module(CommandLineInterface(diag_input, parser, parse_modules_args))

if args.efs_shell:

#print("--efs-shell with", args.efs_shell)
if diag_input.modules:
error('You can not both specify the use of EFS shell and a module')
exit()

from .modules.efs_shell import EfsShell
diag_input.add_module(EfsShell(diag_input))
diag_input.add_module(EfsShell(diag_input,args.efs_shell))



Expand Down
18 changes: 12 additions & 6 deletions src/modules/efs_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,20 @@

class EfsShell:

def __init__(self, diag_input : BaseInput):
def __init__(self, diag_input : BaseInput,fs_type: str = 'efs'):

self.diag_input : BaseInput = diag_input

self.fs_type = fs_type
#print("EfsShell", self.fs_type)
self.parser = ArgumentParser(description = 'Spawn an interactive shell to navigate within the embedded filesystem (EFS) of the baseband device.', prog = '')

self.sub_parsers : _SubParsersAction = self.parser.add_subparsers()

self.sub_parser_command_name_to_command_object : Dict[str, BaseEfsShellCommand] = {}

for command_class in ALL_COMMAND_CLASSES:
command_object = command_class()

command_object = command_class(fs_type)

sub_parser = command_object.get_argument_parser(self.sub_parsers) # Will populate the "self.sub_parsers._name_parser_map" map, see the source of "argparse.py" in Python's standard library for reference

Expand Down Expand Up @@ -129,9 +130,14 @@ def on_init(self):
self.print_help()

def send_efs_handshake(self):

if self.fs_type == 'efs':
subsys_code = DIAG_SUBSYS_FS # Assuming DIAG_SUBSYS_FS is the code for primary
elif self.fs_type == 'efs2':
subsys_code = DIAG_SUBSYS_FS_ALTERNATE
else:
raise ValueError("Invalid filesystem type specified.")
opcode, payload = self.diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BH6I3II',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_HELLO, # Command code
0x100000, # Put all the windows size to high values, let the device negociate these down
0x100000,
Expand Down
5 changes: 4 additions & 1 deletion src/modules/efs_shell_commands/_base_efs_shell_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
from argparse import ArgumentParser, _SubParsersAction, Namespace

class BaseEfsShellCommand:

# Initialization method, add an attribute used to store the file system type
def __init__(self, fs_type='efs'):
self.fs_type = fs_type

def get_argument_parser(self, subparsers_object : _SubParsersAction) -> ArgumentParser:

pass

def execute_command(self, diag_input, args : Namespace):

pass
20 changes: 16 additions & 4 deletions src/modules/efs_shell_commands/cat.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@

class CatCommand(BaseEfsShellCommand):

#Add new parameter efs_type to the initialization method
def __init__(self, efs_type=None):
# Save efs_type for use by other methods of the class
self.efs_type = efs_type
# Call the parent class's initialization method, if necessary
super().__init__(fs_type=efs_type)

def get_argument_parser(self, subparsers_object : _SubParsersAction) -> ArgumentParser:

argument_parser = subparsers_object.add_parser('cat',
Expand All @@ -26,9 +33,14 @@ def get_argument_parser(self, subparsers_object : _SubParsersAction) -> Argument
return argument_parser

def execute_command(self, diag_input, args : Namespace):

if self.fs_type == 'efs':
subsys_code = DIAG_SUBSYS_FS # Assuming DIAG_SUBSYS_FS is the code for primary
elif self.fs_type == 'efs2':
subsys_code = DIAG_SUBSYS_FS_ALTERNATE
else:
raise ValueError("Invalid filesystem type specified.")
opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHii',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_OPEN,
0x0, # oflag - "O_RDONLY"
0, # mode (ignored)
Expand All @@ -55,7 +67,7 @@ def execute_command(self, diag_input, args : Namespace):
while True:

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHiII',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_READ,
file_fd, # File descriptor to read from
BYTES_TO_READ, # Bytes to read at once
Expand Down Expand Up @@ -123,7 +135,7 @@ def execute_command(self, diag_input, args : Namespace):
finally:

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHi',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_CLOSE,
file_fd
))
Expand Down
20 changes: 16 additions & 4 deletions src/modules/efs_shell_commands/chmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
from ...protocol.efs2 import *

class ChmodCommand(BaseEfsShellCommand):

#Add new parameter efs_type to the initialization method
def __init__(self, efs_type=None):
# Save efs_type for use by other methods of the class
self.efs_type = efs_type
# Call the parent class's initialization method, if necessary
super().__init__(fs_type=efs_type)

def get_argument_parser(self, subparsers_object : _SubParsersAction) -> ArgumentParser:

argument_parser = subparsers_object.add_parser('chmod',
Expand All @@ -34,7 +40,13 @@ def get_argument_parser(self, subparsers_object : _SubParsersAction) -> Argument
return argument_parser

def execute_command(self, diag_input, args : Namespace):

if self.fs_type == 'efs':
subsys_code = DIAG_SUBSYS_FS # Assuming DIAG_SUBSYS_FS is the code for primary
elif self.fs_type == 'efs2':
subsys_code = DIAG_SUBSYS_FS_ALTERNATE
else:
raise ValueError("Invalid filesystem type specified.")

try:
assert int(args.octal_perms, 8) & ~0o777 == 0
except Exception:
Expand All @@ -47,7 +59,7 @@ def execute_command(self, diag_input, args : Namespace):
is_directory : bool = False

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BH',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_STAT,
) + args.file_path.encode('latin1').decode('unicode_escape').encode('latin1') + b'\x00', accept_error = True)

Expand Down Expand Up @@ -106,7 +118,7 @@ def execute_command(self, diag_input, args : Namespace):
# Then, actually open the file for write and/or creation

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHH',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_CHMOD,
file_mode
) + args.file_path.encode('latin1').decode('unicode_escape').encode('latin1') + b'\x00', accept_error = True)
Expand Down
17 changes: 14 additions & 3 deletions src/modules/efs_shell_commands/device_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
from ...protocol.efs2 import *

class DeviceInfoCommand(BaseEfsShellCommand):

#Add new parameter efs_type to the initialization method
def __init__(self, efs_type=None):
# Save efs_type for use by other methods of the class
self.efs_type = efs_type
# Call the parent class's initialization method, if necessary
super().__init__(fs_type=efs_type)

def get_argument_parser(self, subparsers_object : _SubParsersAction) -> ArgumentParser:

argument_parser = subparsers_object.add_parser('device_info',
Expand All @@ -24,13 +30,18 @@ def get_argument_parser(self, subparsers_object : _SubParsersAction) -> Argument
return argument_parser

def execute_command(self, diag_input, args : Namespace):

if self.fs_type == 'efs':
subsys_code = DIAG_SUBSYS_FS # Assuming DIAG_SUBSYS_FS is the code for primary
elif self.fs_type == 'efs2':
subsys_code = DIAG_SUBSYS_FS_ALTERNATE
else:
raise ValueError("Invalid filesystem type specified.")
# Obtain the EFS underlying flash device information

sequence_number = randint(0, 0xffff)

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BH',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_DEV_INFO), accept_error = True)

if opcode != DIAG_SUBSYS_CMD_F:
Expand Down
20 changes: 15 additions & 5 deletions src/modules/efs_shell_commands/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
from ...protocol.efs2 import *

class GetCommand(BaseEfsShellCommand):

#Add new parameter efs_type to the initialization method
def __init__(self, efs_type=None):
# Save efs_type for use by other methods of the class
self.efs_type = efs_type
# Call the parent class's initialization method, if necessary
super().__init__(fs_type=efs_type)
def get_argument_parser(self, subparsers_object : _SubParsersAction) -> ArgumentParser:

argument_parser = subparsers_object.add_parser('get',
Expand All @@ -27,7 +32,12 @@ def get_argument_parser(self, subparsers_object : _SubParsersAction) -> Argument
return argument_parser

def execute_command(self, diag_input, args : Namespace):

if self.fs_type == 'efs':
subsys_code = DIAG_SUBSYS_FS # Assuming DIAG_SUBSYS_FS is the code for primary
elif self.fs_type == 'efs2':
subsys_code = DIAG_SUBSYS_FS_ALTERNATE
else:
raise ValueError("Invalid filesystem type specified.")
remote_src : str = args.remote_src
local_dst : str = expanduser(args.local_dst or (getcwd() + '/' + basename(remote_src)))

Expand All @@ -39,7 +49,7 @@ def execute_command(self, diag_input, args : Namespace):
return

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHii',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_OPEN,
0x0, # oflag - "O_RDONLY"
0, # mode (ignored)
Expand All @@ -66,7 +76,7 @@ def execute_command(self, diag_input, args : Namespace):
while True:

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHiII',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_READ,
file_fd, # File descriptor to read from
BYTES_TO_READ, # Bytes to read at once
Expand Down Expand Up @@ -94,7 +104,7 @@ def execute_command(self, diag_input, args : Namespace):
finally:

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHi',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_CLOSE,
file_fd
))
Expand Down
16 changes: 13 additions & 3 deletions src/modules/efs_shell_commands/ln.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
from ...protocol.efs2 import *

class LnCommand(BaseEfsShellCommand):

#Add new parameter efs_type to the initialization method
def __init__(self, efs_type=None):
# Save efs_type for use by other methods of the class
self.efs_type = efs_type
# Call the parent class's initialization method, if necessary
super().__init__(fs_type=efs_type)
def get_argument_parser(self, subparsers_object : _SubParsersAction) -> ArgumentParser:

argument_parser = subparsers_object.add_parser('ln',
Expand All @@ -27,11 +32,16 @@ def get_argument_parser(self, subparsers_object : _SubParsersAction) -> Argument
return argument_parser

def execute_command(self, diag_input, args : Namespace):

if self.fs_type == 'efs':
subsys_code = DIAG_SUBSYS_FS # Assuming DIAG_SUBSYS_FS is the code for primary
elif self.fs_type == 'efs2':
subsys_code = DIAG_SUBSYS_FS_ALTERNATE
else:
raise ValueError("Invalid filesystem type specified.")
# Rename the target path

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BH',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_SYMLINK,
) + args.remote_newlink.encode('latin1').decode('unicode_escape').encode('latin1') + b'\x00'
+ args.remote_target.encode('latin1').decode('unicode_escape').encode('latin1') + b'\x00', accept_error = True)
Expand Down
24 changes: 18 additions & 6 deletions src/modules/efs_shell_commands/ls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
from os import strerror

class LsCommand(BaseEfsShellCommand):

#Add new parameter efs_type to the initialization method
def __init__(self, efs_type=None):
# Save efs_type for use by other methods of the class
self.efs_type = efs_type
# Call the parent class's initialization method, if necessary
super().__init__(fs_type=efs_type)

def get_argument_parser(self, subparsers_object : _SubParsersAction) -> ArgumentParser:

argument_parser = subparsers_object.add_parser('ls',
Expand All @@ -26,9 +32,15 @@ def get_argument_parser(self, subparsers_object : _SubParsersAction) -> Argument
return argument_parser

def execute_command(self, diag_input, args : Namespace):

#print("LsCommand", self.fs_type)
if self.fs_type == 'efs':
subsys_code = DIAG_SUBSYS_FS # Assuming DIAG_SUBSYS_FS is the code for primary
elif self.fs_type == 'efs2':
subsys_code = DIAG_SUBSYS_FS_ALTERNATE
else:
raise ValueError("Invalid filesystem type specified.")
opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BH',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_OPENDIR
) + args.path.encode('latin1').decode('unicode_escape').encode('latin1') + b'\x00', accept_error = True)

Expand All @@ -53,7 +65,7 @@ def execute_command(self, diag_input, args : Namespace):
while True: # Iterate over directory files

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHIi',
DIAG_SUBSYS_FS, # Command subsystem number,
subsys_code, # Command subsystem number,
EFS2_DIAG_READDIR,
dir_fd, sequence_number), accept_error = False)

Expand Down Expand Up @@ -92,7 +104,7 @@ def execute_command(self, diag_input, args : Namespace):
if mode & 0o170000 == 0o120000: # S_IFLNK

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BH',
DIAG_SUBSYS_FS, # Command subsystem number,
subsys_code, # Command subsystem number,
EFS2_DIAG_READLINK) + entry_path.rstrip(b'\x00') + b'\x00', accept_error = False)

readlink_struct = '<BHI'
Expand Down Expand Up @@ -146,7 +158,7 @@ def execute_command(self, diag_input, args : Namespace):
finally:

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHi',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_CLOSEDIR,
dir_fd
))
Expand Down
16 changes: 13 additions & 3 deletions src/modules/efs_shell_commands/md5sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
from ...protocol.efs2 import *

class Md5sumCommand(BaseEfsShellCommand):

#Add new parameter efs_type to the initialization method
def __init__(self, efs_type=None):
# Save efs_type for use by other methods of the class
self.efs_type = efs_type
# Call the parent class's initialization method, if necessary
super().__init__(fs_type=efs_type)
def get_argument_parser(self, subparsers_object : _SubParsersAction) -> ArgumentParser:

argument_parser = subparsers_object.add_parser('md5sum',
Expand All @@ -26,13 +31,18 @@ def get_argument_parser(self, subparsers_object : _SubParsersAction) -> Argument
return argument_parser

def execute_command(self, diag_input, args : Namespace):

if self.fs_type == 'efs':
subsys_code = DIAG_SUBSYS_FS # Assuming DIAG_SUBSYS_FS is the code for primary
elif self.fs_type == 'efs2':
subsys_code = DIAG_SUBSYS_FS_ALTERNATE
else:
raise ValueError("Invalid filesystem type specified.")
# Obtain the file checksum

sequence_number = randint(0, 0xffff)

opcode, payload = diag_input.send_recv(DIAG_SUBSYS_CMD_F, pack('<BHH',
DIAG_SUBSYS_FS, # Command subsystem number
subsys_code, # Command subsystem number
EFS2_DIAG_MKDIR,
sequence_number
) + args.path.encode('latin1').decode('unicode_escape').encode('latin1') + b'\x00', accept_error = True)
Expand Down
Loading