gpdaniels / spike-prime

Experiments with the LEGO Mindstorms (51515) and SPIKE Prime (45678)
MIT License
282 stars 39 forks source link

Decompiled .mpy files #6

Closed mikhasd closed 3 years ago

mikhasd commented 3 years ago

Hi!

I've been working on understanding Spike Prime Hub internals as well. Were you able to decompile the .mpy files or reverse engineer the ujson protocol?

gpdaniels commented 3 years ago

I've not come across any simple method of decompiling the mpy files. There's a python program that is part of the micropython project called mpy-tool.py which can provide some information.

e.g. if I run python3 mpy-tool.py -d hub_runtime.mpy on the latest mindstorms release 2.1.4.10, I get this:

// frozen bytecode for file hub_runtime.py, scope init_tick
STATIC const byte fun_data_init_tick[33] = {
    0x3e, 0x0a,
    MP_QSTR_tick & 0xff, MP_QSTR_tick >> 8,
    MP_QSTR_hub_runtime_dot_py & 0xff, MP_QSTR_hub_runtime_dot_py >> 8,
    0x00,
    0x48, 0x08, 0x00, 
    0x25, 0x00, 
    0x34, 0x00, 
    0x59, 
    0x4a, 0x0d, 0x00, 
    0x57, 
    0x12, MP_QSTR_StopIteration & 0xff, MP_QSTR_StopIteration >> 8, 
    0xdf, 
    0x44, 0x04, 0x80, 
    0x59, 
    0x4a, 0x01, 0x00, 
    0x5d, 
    0x51, 
    0x63, 
};
STATIC const mp_rom_obj_t const_table_data_init_tick[2] = {
    MP_ROM_QSTR(MP_QSTR__star_),
    MP_ROM_QSTR(MP_QSTR__),
};
STATIC const mp_raw_code_t raw_code_init_tick = {
    .kind = MP_CODE_BYTECODE,
    .scope_flags = 0x00,
    .n_pos_args = 2,
    .fun_data = fun_data_init_tick,
    .const_table = (mp_uint_t*)const_table_data_init_tick,
    #if MICROPY_PERSISTENT_CODE_SAVE
    .fun_data_len = 33,
    .n_obj = 0,
    .n_raw_code = 0,
    #if MICROPY_PY_SYS_SETTRACE
    .prelude = {
        .n_state = 8,
        .n_exc_stack = 1,
        .scope_flags = 0,
        .n_pos_args = 2,
        .n_kwonly_args = 0,
        .n_def_pos_args = 0,
        .qstr_block_name = MP_QSTR_tick,
        .qstr_source_file = MP_QSTR_hub_runtime_dot_py,
        .line_info = fun_data_init_tick + 6,
        .opcodes = fun_data_init_tick + 7,
    },
    .line_of_definition = 0,
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .prelude_offset = 0,
    .n_qstr = 0,
    .qstr_link = NULL,
    #endif
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .type_sig = 0,
    #endif
};

// frozen bytecode for file hub_runtime.py, scope init_<lambda>
STATIC const byte fun_data_init__lt_lambda_gt_[18] = {
    0x33, 0x0a,
    MP_QSTR__lt_lambda_gt_ & 0xff, MP_QSTR__lt_lambda_gt_ >> 8,
    MP_QSTR_hub_runtime_dot_py & 0xff, MP_QSTR_hub_runtime_dot_py >> 8,
    0x00,
    0x12, MP_QSTR___connection_changed & 0xff, MP_QSTR___connection_changed >> 8, 
    0x25, 0x01, 
    0x25, 0x00, 
    0xb2, 
    0x34, 0x03, 
    0x63, 
};
STATIC const mp_rom_obj_t const_table_data_init__lt_lambda_gt_[3] = {
    MP_ROM_QSTR(MP_QSTR__star_),
    MP_ROM_QSTR(MP_QSTR__star_),
    MP_ROM_QSTR(MP_QSTR_is_connected),
};
STATIC const mp_raw_code_t raw_code_init__lt_lambda_gt_ = {
    .kind = MP_CODE_BYTECODE,
    .scope_flags = 0x00,
    .n_pos_args = 3,
    .fun_data = fun_data_init__lt_lambda_gt_,
    .const_table = (mp_uint_t*)const_table_data_init__lt_lambda_gt_,
    #if MICROPY_PERSISTENT_CODE_SAVE
    .fun_data_len = 18,
    .n_obj = 0,
    .n_raw_code = 0,
    #if MICROPY_PY_SYS_SETTRACE
    .prelude = {
        .n_state = 7,
        .n_exc_stack = 0,
        .scope_flags = 0,
        .n_pos_args = 3,
        .n_kwonly_args = 0,
        .n_def_pos_args = 0,
        .qstr_block_name = MP_QSTR__lt_lambda_gt_,
        .qstr_source_file = MP_QSTR_hub_runtime_dot_py,
        .line_info = fun_data_init__lt_lambda_gt_ + 6,
        .opcodes = fun_data_init__lt_lambda_gt_ + 7,
    },
    .line_of_definition = 0,
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .prelude_offset = 0,
    .n_qstr = 0,
    .qstr_link = NULL,
    #endif
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .type_sig = 0,
    #endif
};

// frozen bytecode for file hub_runtime.py, scope init_<lambda>
STATIC const byte fun_data_init__lt_lambda_gt_2[19] = {
    0x22, 0x0a,
    MP_QSTR__lt_lambda_gt_ & 0xff, MP_QSTR__lt_lambda_gt_ >> 8,
    MP_QSTR_hub_runtime_dot_py & 0xff, MP_QSTR_hub_runtime_dot_py >> 8,
    0x00,
    0x12, MP_QSTR_notify_gesture_event & 0xff, MP_QSTR_notify_gesture_event >> 8, 
    0x25, 0x00, 
    0x13, MP_QSTR_json_rpc & 0xff, MP_QSTR_json_rpc >> 8, 
    0xb1, 
    0x34, 0x02, 
    0x63, 
};
STATIC const mp_rom_obj_t const_table_data_init__lt_lambda_gt_2[2] = {
    MP_ROM_QSTR(MP_QSTR__star_),
    MP_ROM_QSTR(MP_QSTR_g),
};
STATIC const mp_raw_code_t raw_code_init__lt_lambda_gt_2 = {
    .kind = MP_CODE_BYTECODE,
    .scope_flags = 0x00,
    .n_pos_args = 2,
    .fun_data = fun_data_init__lt_lambda_gt_2,
    .const_table = (mp_uint_t*)const_table_data_init__lt_lambda_gt_2,
    #if MICROPY_PERSISTENT_CODE_SAVE
    .fun_data_len = 19,
    .n_obj = 0,
    .n_raw_code = 0,
    #if MICROPY_PY_SYS_SETTRACE
    .prelude = {
        .n_state = 5,
        .n_exc_stack = 0,
        .scope_flags = 0,
        .n_pos_args = 2,
        .n_kwonly_args = 0,
        .n_def_pos_args = 0,
        .qstr_block_name = MP_QSTR__lt_lambda_gt_,
        .qstr_source_file = MP_QSTR_hub_runtime_dot_py,
        .line_info = fun_data_init__lt_lambda_gt_2 + 6,
        .opcodes = fun_data_init__lt_lambda_gt_2 + 7,
    },
    .line_of_definition = 0,
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .prelude_offset = 0,
    .n_qstr = 0,
    .qstr_link = NULL,
    #endif
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .type_sig = 0,
    #endif
};

// frozen bytecode for file hub_runtime.py, scope init
STATIC const byte fun_data_init[307] = {
    0xa2, 0x11, 0x8b, 0x01,
    MP_QSTR_init & 0xff, MP_QSTR_init >> 8,
    MP_QSTR_hub_runtime_dot_py & 0xff, MP_QSTR_hub_runtime_dot_py >> 8,
    0x00, 0x08, 0x09, 0x0a,
    0x12, MP_QSTR_RPCProtocol & 0xff, MP_QSTR_RPCProtocol >> 8, 
    0x12, MP_QSTR_BT_VCP & 0xff, MP_QSTR_BT_VCP >> 8, 
    0x14, MP_QSTR_isconnected & 0xff, MP_QSTR_isconnected >> 8, 
    0x36, 0x00, 
    0x44, 0x06, 0x80, 
    0x12, MP_QSTR_BT_VCP & 0xff, MP_QSTR_BT_VCP >> 8, 
    0x42, 0x03, 0x80, 
    0x12, MP_QSTR_USB_VCP & 0xff, MP_QSTR_USB_VCP >> 8, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x34, 0x02, 
    0x27, 0x08, 
    0x12, MP_QSTR_register_ports & 0xff, MP_QSTR_register_ports >> 8, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_callbacks & 0xff, MP_QSTR_callbacks >> 8, 
    0x13, MP_QSTR_port_callbacks & 0xff, MP_QSTR_port_callbacks >> 8, 
    0x34, 0x01, 
    0x59, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_callbacks & 0xff, MP_QSTR_callbacks >> 8, 
    0x13, MP_QSTR_port_callbacks & 0xff, MP_QSTR_port_callbacks >> 8, 
    0x14, MP_QSTR_init_attach & 0xff, MP_QSTR_init_attach >> 8, 
    0x36, 0x00, 
    0x59, 
    0x25, 0x08, 
    0x14, MP_QSTR_looper & 0xff, MP_QSTR_looper >> 8, 
    0x36, 0x00, 
    0xc2, 
    0xb2, 
    0x13, MP_QSTR___next__ & 0xff, MP_QSTR___next__ >> 8, 
    0x27, 0x09, 
    0xb9, 
    0x20, 0x02, 0x01, 
    0xc3, 
    0x12, MP_QSTR_RTTimer & 0xff, MP_QSTR_RTTimer >> 8, 
    0xb0, 
    0xb3, 
    0x34, 0x02, 
    0xc4, 
    0x12, MP_QSTR_ProgramRunner & 0xff, MP_QSTR_ProgramRunner >> 8, 
    0x25, 0x08, 
    0x13, MP_QSTR_json_rpc & 0xff, MP_QSTR_json_rpc >> 8, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0xb4, 
    0x34, 0x03, 
    0xc5, 
    0x12, MP_QSTR_HubUI & 0xff, MP_QSTR_HubUI >> 8, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0xb5, 
    0xb1, 
    0x34, 0x03, 
    0x27, 0x0a, 
    0x12, MP_QSTR_error_handler & 0xff, MP_QSTR_error_handler >> 8, 
    0x14, MP_QSTR_initialize & 0xff, MP_QSTR_initialize >> 8, 
    0x25, 0x0a, 
    0x25, 0x08, 
    0x36, 0x02, 
    0x59, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_callbacks & 0xff, MP_QSTR_callbacks >> 8, 
    0x13, MP_QSTR_connection & 0xff, MP_QSTR_connection >> 8, 
    0x13, MP_QSTR_state & 0xff, MP_QSTR_state >> 8, 
    0x14, MP_QSTR_register_persistent & 0xff, MP_QSTR_register_persistent >> 8, 
    0xb8, 
    0xba, 
    0x20, 0x03, 0x02, 
    0x36, 0x01, 
    0x59, 
    0x25, 0x08, 
    0x13, MP_QSTR_json_rpc & 0xff, MP_QSTR_json_rpc >> 8, 
    0xc6, 
    0x12, MP_QSTR_LightMethods & 0xff, MP_QSTR_LightMethods >> 8, 
    0xb6, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_display & 0xff, MP_QSTR_display >> 8, 
    0x34, 0x02, 
    0x12, MP_QSTR_LinegraphMonitorMethods & 0xff, MP_QSTR_LinegraphMonitorMethods >> 8, 
    0xb6, 
    0xb5, 
    0x34, 0x02, 
    0x12, MP_QSTR_MotorMethods & 0xff, MP_QSTR_MotorMethods >> 8, 
    0xb6, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_motors & 0xff, MP_QSTR_motors >> 8, 
    0x34, 0x02, 
    0x12, MP_QSTR_MoveMethods & 0xff, MP_QSTR_MoveMethods >> 8, 
    0xb6, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_move & 0xff, MP_QSTR_move >> 8, 
    0x34, 0x02, 
    0x12, MP_QSTR_SoundMethods & 0xff, MP_QSTR_SoundMethods >> 8, 
    0xb6, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_sound & 0xff, MP_QSTR_sound >> 8, 
    0x34, 0x02, 
    0x12, MP_QSTR_WaitMethods & 0xff, MP_QSTR_WaitMethods >> 8, 
    0xb6, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_callbacks & 0xff, MP_QSTR_callbacks >> 8, 
    0x34, 0x02, 
    0x12, MP_QSTR_ProgramMethods & 0xff, MP_QSTR_ProgramMethods >> 8, 
    0xb6, 
    0x25, 0x0a, 
    0x34, 0x02, 
    0x12, MP_QSTR_HubMethods & 0xff, MP_QSTR_HubMethods >> 8, 
    0xb6, 
    0xb5, 
    0x34, 0x02, 
    0x2b, 0x08, 
    0xc7, 
    0x25, 0x08, 
    0x14, MP_QSTR_register_method_handlers & 0xff, MP_QSTR_register_method_handlers >> 8, 
    0xb7, 
    0x36, 0x01, 
    0x59, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_callbacks & 0xff, MP_QSTR_callbacks >> 8, 
    0x13, MP_QSTR_button_callbacks & 0xff, MP_QSTR_button_callbacks >> 8, 
    0x14, MP_QSTR_register_rpc_handlers & 0xff, MP_QSTR_register_rpc_handlers >> 8, 
    0x25, 0x08, 
    0x13, MP_QSTR_json_rpc & 0xff, MP_QSTR_json_rpc >> 8, 
    0x36, 0x01, 
    0x59, 
    0x12, MP_QSTR_system & 0xff, MP_QSTR_system >> 8, 
    0x13, MP_QSTR_callbacks & 0xff, MP_QSTR_callbacks >> 8, 
    0x13, MP_QSTR_gesture_callback & 0xff, MP_QSTR_gesture_callback >> 8, 
    0x14, MP_QSTR_register_persistent & 0xff, MP_QSTR_register_persistent >> 8, 
    0xb8, 
    0x20, 0x04, 0x01, 
    0x36, 0x01, 
    0x59, 
    0x25, 0x0a, 
    0xb4, 
    0x2a, 0x02, 
    0x63, 
};
STATIC const mp_rom_obj_t const_table_data_init[5] = {
    MP_ROM_QSTR(MP_QSTR_timer),
    MP_ROM_QSTR(MP_QSTR_slotid),
    MP_ROM_PTR(&raw_code_init_tick),
    MP_ROM_PTR(&raw_code_init__lt_lambda_gt_),
    MP_ROM_PTR(&raw_code_init__lt_lambda_gt_2),
};
STATIC const mp_raw_code_t raw_code_init = {
    .kind = MP_CODE_BYTECODE,
    .scope_flags = 0x00,
    .n_pos_args = 2,
    .fun_data = fun_data_init,
    .const_table = (mp_uint_t*)const_table_data_init,
    #if MICROPY_PERSISTENT_CODE_SAVE
    .fun_data_len = 307,
    .n_obj = 0,
    .n_raw_code = 3,
    #if MICROPY_PY_SYS_SETTRACE
    .prelude = {
        .n_state = 21,
        .n_exc_stack = 0,
        .scope_flags = 0,
        .n_pos_args = 2,
        .n_kwonly_args = 0,
        .n_def_pos_args = 1,
        .qstr_block_name = MP_QSTR_init,
        .qstr_source_file = MP_QSTR_hub_runtime_dot_py,
        .line_info = fun_data_init + 8,
        .opcodes = fun_data_init + 12,
    },
    .line_of_definition = 0,
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .prelude_offset = 0,
    .n_qstr = 0,
    .qstr_link = NULL,
    #endif
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .type_sig = 0,
    #endif
};

// frozen bytecode for file hub_runtime.py, scope start_exc_handler
STATIC const byte fun_data_start_exc_handler[27] = {
    0x22, 0x0a,
    MP_QSTR_exc_handler & 0xff, MP_QSTR_exc_handler >> 8,
    MP_QSTR_hub_runtime_dot_py & 0xff, MP_QSTR_hub_runtime_dot_py >> 8,
    0x00,
    0x12, MP_QSTR_error_handler & 0xff, MP_QSTR_error_handler >> 8, 
    0x14, MP_QSTR_handle_runtime_error & 0xff, MP_QSTR_handle_runtime_error >> 8, 
    0xb1, 
    0x36, 0x01, 
    0x59, 
    0x25, 0x00, 
    0x14, MP_QSTR_stop_all & 0xff, MP_QSTR_stop_all >> 8, 
    0x36, 0x00, 
    0x59, 
    0x51, 
    0x63, 
};
STATIC const mp_rom_obj_t const_table_data_start_exc_handler[2] = {
    MP_ROM_QSTR(MP_QSTR__star_),
    MP_ROM_QSTR(MP_QSTR_e),
};
STATIC const mp_raw_code_t raw_code_start_exc_handler = {
    .kind = MP_CODE_BYTECODE,
    .scope_flags = 0x00,
    .n_pos_args = 2,
    .fun_data = fun_data_start_exc_handler,
    .const_table = (mp_uint_t*)const_table_data_start_exc_handler,
    #if MICROPY_PERSISTENT_CODE_SAVE
    .fun_data_len = 27,
    .n_obj = 0,
    .n_raw_code = 0,
    #if MICROPY_PY_SYS_SETTRACE
    .prelude = {
        .n_state = 5,
        .n_exc_stack = 0,
        .scope_flags = 0,
        .n_pos_args = 2,
        .n_kwonly_args = 0,
        .n_def_pos_args = 0,
        .qstr_block_name = MP_QSTR_exc_handler,
        .qstr_source_file = MP_QSTR_hub_runtime_dot_py,
        .line_info = fun_data_start_exc_handler + 6,
        .opcodes = fun_data_start_exc_handler + 7,
    },
    .line_of_definition = 0,
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .prelude_offset = 0,
    .n_qstr = 0,
    .qstr_link = NULL,
    #endif
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .type_sig = 0,
    #endif
};

// frozen bytecode for file hub_runtime.py, scope start
STATIC const byte fun_data_start[192] = {
    0x6c, 0x0b,
    MP_QSTR_start & 0xff, MP_QSTR_start >> 8,
    MP_QSTR_hub_runtime_dot_py & 0xff, MP_QSTR_hub_runtime_dot_py >> 8,
    0x00, 0x07,
    0x12, MP_QSTR_pop_force_reset & 0xff, MP_QSTR_pop_force_reset >> 8, 
    0x34, 0x00, 
    0xc0, 
    0xb0, 
    0x44, 0x0c, 0x80, 
    0xb0, 
    0x14, MP_QSTR_get & 0xff, MP_QSTR_get >> 8, 
    0x10, MP_QSTR_suppress & 0xff, MP_QSTR_suppress >> 8, 
    0x36, 0x01, 
    0x42, 0x01, 0x80, 
    0x51, 
    0xc1, 
    0xb1, 
    0x44, 0x31, 0x80, 
    0x12, MP_QSTR_hub & 0xff, MP_QSTR_hub >> 8, 
    0x13, MP_QSTR_display & 0xff, MP_QSTR_display >> 8, 
    0x14, MP_QSTR_show & 0xff, MP_QSTR_show >> 8, 
    0x12, MP_QSTR_hub & 0xff, MP_QSTR_hub >> 8, 
    0x14, MP_QSTR_Image & 0xff, MP_QSTR_Image >> 8, 
    0xb1, 
    0x36, 0x01, 
    0x36, 0x01, 
    0x59, 
    0xb0, 
    0x14, MP_QSTR_get & 0xff, MP_QSTR_get >> 8, 
    0x23, 0x00, 
    0x36, 0x01, 
    0x44, 0x0f, 0x80, 
    0x12, MP_QSTR_hub & 0xff, MP_QSTR_hub >> 8, 
    0x13, MP_QSTR_bluetooth & 0xff, MP_QSTR_bluetooth >> 8, 
    0x14, MP_QSTR_discoverable & 0xff, MP_QSTR_discoverable >> 8, 
    0x22, 0x80, 0x78, 
    0x36, 0x01, 
    0x59, 
    0x51, 
    0x63, 
    0xb0, 
    0x44, 0x08, 0x80, 
    0xb0, 
    0x10, MP_QSTR_slotid & 0xff, MP_QSTR_slotid >> 8, 
    0x55, 
    0x42, 0x01, 0x80, 
    0x51, 
    0xc2, 
    0x12, MP_QSTR_Timer & 0xff, MP_QSTR_Timer >> 8, 
    0x7f, 
    0x34, 0x01, 
    0xc3, 
    0x12, MP_QSTR_init & 0xff, MP_QSTR_init >> 8, 
    0xb3, 
    0xb2, 
    0x34, 0x02, 
    0x30, 0x02, 
    0x27, 0x07, 
    0xc4, 
    0xb4, 
    0x14, MP_QSTR_start & 0xff, MP_QSTR_start >> 8, 
    0x10, MP_QSTR_period & 0xff, MP_QSTR_period >> 8, 
    0x12, MP_QSTR_TIMER_PACE_HIGH & 0xff, MP_QSTR_TIMER_PACE_HIGH >> 8, 
    0x36, 0x82, 0x00, 
    0x59, 
    0xb7, 
    0x20, 0x01, 0x01, 
    0xc5, 
    0x12, MP_QSTR_get_event_loop & 0xff, MP_QSTR_get_event_loop >> 8, 
    0x34, 0x00, 
    0xc6, 
    0x48, 0x0b, 0x00, 
    0xb6, 
    0x14, MP_QSTR_run_forever & 0xff, MP_QSTR_run_forever >> 8, 
    0xb5, 
    0x36, 0x01, 
    0x59, 
    0x4a, 0x15, 0x00, 
    0x57, 
    0x12, MP_QSTR_KeyboardInterrupt & 0xff, MP_QSTR_KeyboardInterrupt >> 8, 
    0xdf, 
    0x44, 0x0c, 0x80, 
    0x59, 
    0xb3, 
    0x14, MP_QSTR_deinit & 0xff, MP_QSTR_deinit >> 8, 
    0x36, 0x00, 
    0x59, 
    0x64, 
    0x4a, 0x01, 0x00, 
    0x5d, 
    0x12, MP_QSTR_hub & 0xff, MP_QSTR_hub >> 8, 
    0x13, MP_QSTR_display & 0xff, MP_QSTR_display >> 8, 
    0x14, MP_QSTR_clear & 0xff, MP_QSTR_clear >> 8, 
    0x36, 0x00, 
    0x59, 
    0x51, 
    0x63, 
};
STATIC const mp_obj_str_t const_obj_start_0 = {{&mp_type_str}, 92, 12, (const byte*)"\x64\x69\x73\x63\x6f\x76\x65\x72\x61\x62\x6c\x65"};
STATIC const mp_rom_obj_t const_table_data_start[2] = {
    MP_ROM_PTR(&const_obj_start_0),
    MP_ROM_PTR(&raw_code_start_exc_handler),
};
STATIC const mp_raw_code_t raw_code_start = {
    .kind = MP_CODE_BYTECODE,
    .scope_flags = 0x00,
    .n_pos_args = 0,
    .fun_data = fun_data_start,
    .const_table = (mp_uint_t*)const_table_data_start,
    #if MICROPY_PERSISTENT_CODE_SAVE
    .fun_data_len = 192,
    .n_obj = 1,
    .n_raw_code = 1,
    #if MICROPY_PY_SYS_SETTRACE
    .prelude = {
        .n_state = 14,
        .n_exc_stack = 1,
        .scope_flags = 0,
        .n_pos_args = 0,
        .n_kwonly_args = 0,
        .n_def_pos_args = 0,
        .qstr_block_name = MP_QSTR_start,
        .qstr_source_file = MP_QSTR_hub_runtime_dot_py,
        .line_info = fun_data_start + 6,
        .opcodes = fun_data_start + 8,
    },
    .line_of_definition = 0,
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .prelude_offset = 0,
    .n_qstr = 0,
    .qstr_link = NULL,
    #endif
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .type_sig = 0,
    #endif
};

// frozen bytecode for file hub_runtime.py, scope __connection_changed
STATIC const byte fun_data___connection_changed[89] = {
    0x43, 0x0a,
    MP_QSTR___connection_changed & 0xff, MP_QSTR___connection_changed >> 8,
    MP_QSTR_hub_runtime_dot_py & 0xff, MP_QSTR_hub_runtime_dot_py >> 8,
    0x00,
    0xb2, 
    0x30, 0x02, 
    0xc3, 
    0xc4, 
    0xb1, 
    0x13, MP_QSTR_stream & 0xff, MP_QSTR_stream >> 8, 
    0xc5, 
    0xb4, 
    0x44, 0x12, 0x80, 
    0xb5, 
    0x12, MP_QSTR_BT_VCP & 0xff, MP_QSTR_BT_VCP >> 8, 
    0xdc, 
    0x44, 0x0a, 0x80, 
    0x12, MP_QSTR_BT_VCP & 0xff, MP_QSTR_BT_VCP >> 8, 
    0xb1, 
    0x18, MP_QSTR_stream & 0xff, MP_QSTR_stream >> 8, 
    0x42, 0x28, 0x80, 
    0xb1, 
    0x13, MP_QSTR_stream & 0xff, MP_QSTR_stream >> 8, 
    0x12, MP_QSTR_USB_VCP & 0xff, MP_QSTR_USB_VCP >> 8, 
    0xdc, 
    0x44, 0x0a, 0x80, 
    0x12, MP_QSTR_USB_VCP & 0xff, MP_QSTR_USB_VCP >> 8, 
    0xb1, 
    0x18, MP_QSTR_stream & 0xff, MP_QSTR_stream >> 8, 
    0x42, 0x13, 0x80, 
    0x12, MP_QSTR_any & 0xff, MP_QSTR_any >> 8, 
    0xb2, 
    0x34, 0x01, 
    0x43, 0x0a, 0x80, 
    0x12, MP_QSTR_USB_VCP & 0xff, MP_QSTR_USB_VCP >> 8, 
    0xb1, 
    0x18, MP_QSTR_stream & 0xff, MP_QSTR_stream >> 8, 
    0x42, 0x00, 0x80, 
    0xb0, 
    0x14, MP_QSTR_on_connection & 0xff, MP_QSTR_on_connection >> 8, 
    0xb2, 
    0x36, 0x01, 
    0x59, 
    0x51, 
    0x63, 
};
STATIC const mp_rom_obj_t const_table_data___connection_changed[3] = {
    MP_ROM_QSTR(MP_QSTR_hubui),
    MP_ROM_QSTR(MP_QSTR_communication),
    MP_ROM_QSTR(MP_QSTR_is_connected),
};
STATIC const mp_raw_code_t raw_code___connection_changed = {
    .kind = MP_CODE_BYTECODE,
    .scope_flags = 0x00,
    .n_pos_args = 3,
    .fun_data = fun_data___connection_changed,
    .const_table = (mp_uint_t*)const_table_data___connection_changed,
    #if MICROPY_PERSISTENT_CODE_SAVE
    .fun_data_len = 89,
    .n_obj = 0,
    .n_raw_code = 0,
    #if MICROPY_PY_SYS_SETTRACE
    .prelude = {
        .n_state = 9,
        .n_exc_stack = 0,
        .scope_flags = 0,
        .n_pos_args = 3,
        .n_kwonly_args = 0,
        .n_def_pos_args = 0,
        .qstr_block_name = MP_QSTR___connection_changed,
        .qstr_source_file = MP_QSTR_hub_runtime_dot_py,
        .line_info = fun_data___connection_changed + 6,
        .opcodes = fun_data___connection_changed + 7,
    },
    .line_of_definition = 0,
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .prelude_offset = 0,
    .n_qstr = 0,
    .qstr_link = NULL,
    #endif
    #endif
    #if MICROPY_EMIT_MACHINE_CODE
    .type_sig = 0,
    #endif
};
gpdaniels commented 3 years ago

I've not looked into the json protocol yet, but I've seen that there's a couple of other githup projects investigating that.

mikhasd commented 3 years ago

I could do the same. I'd like to discover if is there a way to add new methods to the RPC API in order to create an efficient way to communicate with the hub, allowing a more powerful PC reading the sensors and reacting to it by sending commands to the Hub.

I have the ujson RPC Api which I have reverse engineered.

gpdaniels commented 3 years ago

Because LEGO only provide the precompiled mpy files I think the only way would be to decompile one, insert your methods and upload the changed file. The micropython forums seem to think that writing a script to convert the bytecode back into micropython wouldn't be too hard and the pycopy version of micropython has a disassembly module. I don't think pycopy's module will work with the LEGO code, because LEGO is using quite an old version of micropython.