diff --git a/config/goggles/config.json b/config/goggles/config.json index 5529de8..34ba612 100644 --- a/config/goggles/config.json +++ b/config/goggles/config.json @@ -10,5 +10,6 @@ "fakehd_columns": "S", "fakehd_rows": "WWWWWWCCWWWWWWWD", "rec_enabled": true, - "rec_pb_enabled": true + "rec_pb_enabled": true, + "vtx_msp": false } diff --git a/config/goggles/schema.json b/config/goggles/schema.json index 4127e4e..4477c81 100644 --- a/config/goggles/schema.json +++ b/config/goggles/schema.json @@ -60,6 +60,10 @@ "hide_diagnostics": { "name": "Hide diagnostic information", "widget": "checkbox" + }, + "vtx_msp": { + "name": "Enable VTX MSP", + "widget": "checkbox" } }, "units": [ diff --git a/config/goggles/schemaV2.json b/config/goggles/schemaV2.json index 8c6f246..a25c206 100644 --- a/config/goggles/schemaV2.json +++ b/config/goggles/schemaV2.json @@ -58,7 +58,16 @@ true, false ] - } + }, + "vtx_msp": { + "type": "boolean", + "title": "Enable VTX MSP", + "description": "Control video channel from Betaflight or ELRS Lua script VTX admin", + "enum": [ + true, + false + ] + } }, "dependencies": { "fakehd_enable": { diff --git a/config/goggles/uiSchemaV2.json b/config/goggles/uiSchemaV2.json index 5184fb8..12735de 100644 --- a/config/goggles/uiSchemaV2.json +++ b/config/goggles/uiSchemaV2.json @@ -31,5 +31,8 @@ }, "fakehd_rows": { "ui:help": "FakeHD row alignment config, each character configures the alignment for one row. [Read more](https://github.com/fpv-wtf/msp-osd#customising-the-default-fakehd-grid)" - } + }, + "vtx_msp": { + "ui:help": "Enable VTX MSP protocol to control the video channel from Betaflight or ELRS Lua script VTX admin" + }, } \ No newline at end of file diff --git a/dev_air.sh b/dev_air.sh new file mode 100755 index 0000000..b475376 --- /dev/null +++ b/dev_air.sh @@ -0,0 +1,6 @@ +ndk-build +adb push libs/armeabi-v7a/msp_displayport_mux /blackbox +adb shell setprop dji.hdvt_uav_service 0 +adb shell mv /dev/ttyS1 /dev/ttyS1_moved +adb shell nohup /blackbox/msp_displayport_mux 192.168.41.2 /dev/ttyS1_moved /dev/ttyS1 & +adb shell setprop dji.hdvt_uav_service 1 \ No newline at end of file diff --git a/dev_goggles.sh b/dev_goggles.sh new file mode 100755 index 0000000..2172501 --- /dev/null +++ b/dev_goggles.sh @@ -0,0 +1,4 @@ +ndk-build +adb shell setprop dji.glasses_wm150_service 0 +adb push libs/armeabi-v7a/libdisplayport_osd_shim.so /tmp +adb shell LD_PRELOAD=/tmp/libdisplayport_osd_shim.so dji_gls_wm150_original -g \ No newline at end of file diff --git a/ipk/airunit/control/control b/ipk/airunit/control/control index 79e3559..014dc37 100644 --- a/ipk/airunit/control/control +++ b/ipk/airunit/control/control @@ -1,5 +1,5 @@ Package: msp-osd -Version: 0.10.1 +Version: 0.10.2 Maintainer: bri3d Description: MSP OSD service for the DJI HD FPV airunit. Architecture: pigeon-airside diff --git a/ipk/airunit/data/opt/etc/dinit.d/msp-osd-airside b/ipk/airunit/data/opt/etc/dinit.d/msp-osd-airside index e592674..62be5b3 100644 --- a/ipk/airunit/data/opt/etc/dinit.d/msp-osd-airside +++ b/ipk/airunit/data/opt/etc/dinit.d/msp-osd-airside @@ -1,4 +1,4 @@ type = bgprocess command = /opt/bin/airunit-osd-start.sh pid-file = /opt/var/run/airunit-osd-dji.pid -restart = true +restart = true \ No newline at end of file diff --git a/ipk/goggle/control/control b/ipk/goggle/control/control index 22ae07e..cad63bc 100644 --- a/ipk/goggle/control/control +++ b/ipk/goggle/control/control @@ -1,5 +1,5 @@ Package: msp-osd -Version: 0.11.1 +Version: 0.11.2 Maintainer: bri3d Description: MSP OSD service for the DJI HD FPV goggles. Architecture: pigeon-glasses diff --git a/jni/Android.mk b/jni/Android.mk index 1bb053e..c311674 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -7,7 +7,8 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) -LOCAL_CFLAGS += -fPIC -std=c99 -O3 +LOCAL_CFLAGS += -fPIC -std=c99 -O3 -I. +LOCAL_CXXFLAGS += -fPIC -std=c99 -O3 -I. LOCAL_LDFLAGS += -fPIC LOCAL_LDLIBS := -llog LOCAL_ARM_NEON := true @@ -31,11 +32,14 @@ LOCAL_SRC_FILES := \ rec/rec_util.c \ rec/rec.c \ toast/toast.c \ - util/fs_util.c + util/fs_util.c \ + util/vtx_manager.c include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) +LOCAL_CFLAGS += -fPIC -std=c99 -O3 -I. -DLZ4_STATIC_LINKING_ONLY +LOCAL_CXXFLAGS += -fPIC -std=c99 -O3 -I. LOCAL_SRC_FILES:= \ hw/dji_radio_shm.c \ json/osd_config.c \ diff --git a/jni/hw/dji_display.c b/jni/hw/dji_display.c index 9f40d6c..5bc2668 100644 --- a/jni/hw/dji_display.c +++ b/jni/hw/dji_display.c @@ -1,4 +1,5 @@ #include +#include #include "dji_display.h" #include "util/debug.h" diff --git a/jni/hw/dji_radio_shm.c b/jni/hw/dji_radio_shm.c index 6afbb1b..a151f15 100644 --- a/jni/hw/dji_radio_shm.c +++ b/jni/hw/dji_radio_shm.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/jni/lz4/lz4.c b/jni/lz4/lz4.c index 8796f78..9f9f41e 100644 --- a/jni/lz4/lz4.c +++ b/jni/lz4/lz4.c @@ -114,7 +114,6 @@ #define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */ #endif -#define LZ4_STATIC_LINKING_ONLY /* LZ4_DISTANCE_MAX */ #include "lz4.h" /* see also "memory routines" below */ diff --git a/jni/msp/msp.h b/jni/msp/msp.h index e25b35b..59d978a 100644 --- a/jni/msp/msp.h +++ b/jni/msp/msp.h @@ -17,6 +17,12 @@ #define MSP_CMD_DISPLAYPORT 182 #define MSP_CMD_SET_OSD_CANVAS 188 +// https://github.com/betaflight/betaflight/blob/master/src/main/msp/msp_protocol.h#L201C1-L202C50 +#define MSP_CMD_VTX_CONFIG 88 // from FC +#define MSP_CMD_SET_VTX_CONFIG 89 // to FC +#define MSP_CMD_SET_VTXTABLE_BAND 227 // to FC set vtxTable band/channel data (one band at a time) +#define MSP_CMD_SET_VTXTABLE_POWERLEVEL 228 // to FC set vtxTable powerLevel data (one powerLevel at a time) + typedef enum { MSP_ERR_NONE, MSP_ERR_HDR, @@ -58,4 +64,4 @@ typedef struct msp_state_s { uint16_t msp_data_from_msg(uint8_t message_buffer[], msp_msg_t *msg); msp_error_e construct_msp_command(uint8_t message_buffer[], uint8_t command, uint8_t payload[], uint8_t size, msp_direction_e direction); -msp_error_e msp_process_data(msp_state_t *msp_state, uint8_t dat); \ No newline at end of file +msp_error_e msp_process_data(msp_state_t *msp_state, uint8_t dat); diff --git a/jni/msp/msp_vtx.c b/jni/msp/msp_vtx.c new file mode 100644 index 0000000..e910bac --- /dev/null +++ b/jni/msp/msp_vtx.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include "msp.h" + +static uint8_t message_buffer[256]; + +uint8_t total_bands = 1; +uint8_t total_channels = 8; +uint8_t total_powers = 6; + +uint8_t * resetVTXTableMessage() { + uint8_t payload_size = 15; + uint8_t default_table[15] = { + 0, // idx LSB + 0, // idx MSB + 0, // 25mW Power idx + 0, // pitmode + 0, // lowPowerDisarm + 0, // pitModeFreq LSB + 0, // pitModeFreq MSB + 0, // band + 0, // channel + 0, // newFreq LSB + 0, // newFreq MSB + total_bands, // bandCount, + total_channels, // channelCount + total_powers, // powerCount + 1 // vtxtable should be cleared + }; + + construct_msp_command(message_buffer, MSP_CMD_SET_VTX_CONFIG, default_table, payload_size, MSP_OUTBOUND); + + return message_buffer; +} + +uint8_t * setupVTXPowerMessage(int index, int value, char name[]) { + uint8_t name_size = strlen(name); + uint8_t payload_size = 4 + name_size; + uint8_t vtx_power[4 + 3] = { + index, // idx + value & 0xFF, // powerValue LSB + (value >> 8) & 0xFF, // powerValue MSB + strlen(name), // label lenght + }; + + for(int i = 0; i < strlen(name); i++) { + vtx_power[i] = name[i]; + } + /*txPacket[8] = idx; + txPacket[9] = saPowerLevelsLut[idx - 1] & 0xFF; // powerValue LSB + txPacket[10] = (saPowerLevelsLut[idx - 1] >> 8) & 0xFF; // powerValue MSB + txPacket[11] = POWER_LEVEL_LABEL_LENGTH; + txPacket[12] = saPowerLevelsLabel[((idx - 1) * POWER_LEVEL_LABEL_LENGTH) + 0]; + txPacket[13] = saPowerLevelsLabel[((idx - 1) * POWER_LEVEL_LABEL_LENGTH) + 1]; + txPacket[14] = saPowerLevelsLabel[((idx - 1) * POWER_LEVEL_LABEL_LENGTH) + 2];*/ + + construct_msp_command(message_buffer, MSP_CMD_SET_VTXTABLE_POWERLEVEL, vtx_power, payload_size, MSP_OUTBOUND); + + return message_buffer; +} + +uint8_t * setupVTXBandMessage() { + uint8_t payload_size = 8 + total_channels; + uint8_t vtx_band[8 + 8] = { + 0, // band + 3, // label lenght + 'D', + 'J', + 'I', + 'D', // band letter + 0, // is factory band + total_channels, // total channel + }; + + for(int i = 8; i < total_channels; i++) { + vtx_band[i] = i & 0xFF; + i++; + vtx_band[i] = (i >> 8) & 0xFF; + } + + construct_msp_command(message_buffer, MSP_CMD_SET_VTXTABLE_POWERLEVEL, vtx_band, payload_size, MSP_OUTBOUND); + + return message_buffer; +} diff --git a/jni/msp_displayport_mux.c b/jni/msp_displayport_mux.c index 4a71648..febc87b 100644 --- a/jni/msp_displayport_mux.c +++ b/jni/msp_displayport_mux.c @@ -16,6 +16,7 @@ #include "util/debug.h" #include "util/time_util.h" #include "util/fs_util.h" +#include "./msp/msp_vtx.c" #define CPU_TEMP_PATH "/sys/devices/platform/soc/f0a00000.apb/f0a71000.omc/temp1" #define AU_VOLTAGE_PATH "/sys/devices/platform/soc/f0a00000.apb/f0a71000.omc/voltage4" @@ -74,6 +75,8 @@ static uint8_t serial_passthrough = 1; static uint8_t compress = 0; static uint8_t no_btfl_hd = 0; +int8_t fc_vtx_channel = -1; + static void sig_handler(int _) { quit = 1; @@ -142,6 +145,32 @@ static void send_version_request(int serial_fd) { write(serial_fd, &buffer, sizeof(buffer)); } +static void send_vtx_config_request(int serial_fd) { + DEBUG_PRINT("Sending VTX CONFIG requests message...\n"); + uint8_t buffer[6]; + construct_msp_command(buffer, MSP_CMD_VTX_CONFIG, NULL, 0, MSP_OUTBOUND); + write(serial_fd, &buffer, sizeof(buffer)); +} + +static void send_vtx_set_config_request(int serial_fd) { + DEBUG_PRINT("Sending VTX READY message...\n"); + + uint8_t *buffer = resetVTXTableMessage(); + write(serial_fd, buffer, sizeof(buffer)); + + buffer = setupVTXPowerMessage(0, 25, "25 "); + write(serial_fd, buffer, sizeof(buffer)); + buffer = setupVTXPowerMessage(0, 200, "200 "); + write(serial_fd, buffer, sizeof(buffer)); + buffer = setupVTXPowerMessage(0, 500, "500 "); + write(serial_fd, buffer, sizeof(buffer)); + buffer = setupVTXPowerMessage(0, 700, "700 "); + write(serial_fd, buffer, sizeof(buffer)); + + buffer = setupVTXBandMessage(); + write(serial_fd, buffer, sizeof(buffer)); +} + static void copy_to_msp_frame_buffer(void *buffer, uint16_t size) { memcpy(&frame_buffer[fb_cursor], buffer, size); fb_cursor += size; @@ -208,10 +237,19 @@ static void rx_msp_callback(msp_msg_t *msp_message) } break; } + case MSP_CMD_VTX_CONFIG: { + DEBUG_PRINT("Received VTX CONFIG message...\n"); + if(sizeof(msp_message->payload) > 2) { + fc_vtx_channel = msp_message->payload[2]; + } + } + case MSP_CMD_SET_VTX_CONFIG: { + DEBUG_PRINT("Received SET VTX CONFIG message...\n"); + } default: { uint16_t size = msp_data_from_msg(message_buffer, msp_message); if(serial_passthrough || cache_msp_message(msp_message)) { - // Either serial passthrough was on, or the cache was enabled but missed (a response was not available). + // Either serial passthrough was on, or the cache was enabled but missed (a response was not available). // Either way, this means we need to send the message through to DJI. write(pty_fd, message_buffer, size); } @@ -249,8 +287,9 @@ static void send_data_packet(int data_socket_fd, dji_shm_state_t *dji_shm) { data.version_specifier = 0xFFFF; data.tx_temperature = get_int_from_fs(CPU_TEMP_PATH); data.tx_voltage = get_int_from_fs(AU_VOLTAGE_PATH); + data.fc_vtx_channel = fc_vtx_channel; memcpy(data.fc_variant, current_fc_identifier, sizeof(current_fc_identifier)); - DEBUG_PRINT("got voltage %f V temp %d C variant %.4s\n", (float)(data.tx_voltage / 64.0f), data.tx_temperature, data.fc_variant); + DEBUG_PRINT("got voltage %f V temp %d C variant %.4s and channel %d\n", (float)(data.tx_voltage / 64.0f), data.tx_temperature, data.fc_variant, data.fc_vtx_channel); write(data_socket_fd, &data, sizeof(data)); } @@ -364,8 +403,8 @@ int main(int argc, char *argv[]) { printf("Allocated PTY %s\n", pty_name_ptr); if ((argc - optind) > 2) { unlink(argv[optind + 2]); - symlink(pty_name_ptr, argv[optind + 2]); - printf("Relinked %s to %s\n", argv[optind + 2], pty_name_ptr); + symlink(pty_name_ptr, argv[optind + 2]); + printf("Relinked %s to %s\n", argv[optind + 2], pty_name_ptr); } socket_fd = connect_to_server(ip_address, MSP_PORT); compressed_fd = connect_to_server(ip_address, COMPRESSED_DATA_PORT); @@ -390,6 +429,8 @@ int main(int argc, char *argv[]) { clock_gettime(CLOCK_MONOTONIC, &last_data); clock_gettime(CLOCK_MONOTONIC, &last_frame); + send_vtx_set_config_request(serial_fd); + while (!quit) { poll_fds[0].fd = serial_fd; poll_fds[1].fd = pty_fd; @@ -397,7 +438,7 @@ int main(int argc, char *argv[]) { poll_fds[1].events = POLLIN; poll(poll_fds, 2, ((MSEC_PER_SEC / update_rate_hz) / 2)); - + // We got inbound serial data, process it as MSP data. if (0 < (serial_data_size = read(serial_fd, serial_data, sizeof(serial_data)))) { DEBUG_PRINT("RECEIVED data! length %d\n", serial_data_size); @@ -431,6 +472,8 @@ int main(int argc, char *argv[]) { if(current_fc_identifier[0] == 0) { send_variant_request(serial_fd); } + //INFO: For testing purpose, request VTX_CONFIG + send_vtx_config_request(serial_fd); } if(compress && (timespec_subtract_ns(&now, &last_frame) > (NSEC_PER_SEC / update_rate_hz))) { send_compressed_screen(compressed_fd); diff --git a/jni/net/data_protocol.h b/jni/net/data_protocol.h index 125121b..4427e22 100644 --- a/jni/net/data_protocol.h +++ b/jni/net/data_protocol.h @@ -4,6 +4,7 @@ typedef struct packet_data_s { uint16_t tx_temperature; uint16_t version_specifier; // Used to be bitrate! Danger! 0xFFFF means V2 (no bitrate) for now. uint16_t tx_voltage; + int8_t fc_vtx_channel; char fc_variant[4]; } __attribute__((packed)) packet_data_t; diff --git a/jni/osd_dji_overlay_udp.c b/jni/osd_dji_overlay_udp.c index e9ef091..ad98ee6 100644 --- a/jni/osd_dji_overlay_udp.c +++ b/jni/osd_dji_overlay_udp.c @@ -34,6 +34,8 @@ #include "rec/rec.h" #include "rec/rec_pb.h" +#include "util/vtx_manager.h" + #define MSP_PORT 7654 #define DATA_PORT 7655 #define COMPRESSED_DATA_PORT 7656 @@ -77,6 +79,9 @@ typedef enum #define BACK_BUTTON_DELAY 4 +#define VTX_MPS_CONFIG_KEY "vtx_msp" +static u_int8_t vtx_manager_enabled; + #define SWAP32(data) \ ( (((data) >> 24) & 0x000000FF) | (((data) >> 8) & 0x0000FF00) | \ (((data) << 8) & 0x00FF0000) | (((data) << 24) & 0xFF000000) ) @@ -485,7 +490,7 @@ static void check_is_au_overlay_enabled() static void process_data_packet(uint8_t *buf, int len, dji_shm_state_t *radio_shm) { packet_data_t *packet = (packet_data_t *)buf; - DEBUG_PRINT("got data %04X version spec %d C %f V variant %.4s\n", packet->version_specifier, packet->tx_temperature, packet->tx_voltage / 64.0f, packet->fc_variant); + DEBUG_PRINT("got data %04X version spec %d C %f V variant %.4s and vtx channel %d\n", packet->version_specifier, packet->tx_temperature, packet->tx_voltage / 64.0f, packet->fc_variant, packet->fc_vtx_channel); char str[8]; clear_overlay(); if(au_overlay_enabled) { @@ -494,6 +499,9 @@ static void process_data_packet(uint8_t *buf, int len, dji_shm_state_t *radio_sh snprintf(str, 8, "A %2.1fV", packet->tx_voltage / 64.0f); display_print_string(overlay_display_info.char_width - 7, overlay_display_info.char_height - 7, str, 7); } + if(vtx_manager_enabled == true) { + changeChannel(packet->fc_vtx_channel); + } if(len > 6) { DEBUG_PRINT("Got new packet with variant %.4s\n", packet->fc_variant); // should have FC type @@ -752,6 +760,12 @@ void osd_directfb(duss_disp_instance_handle_t *disp, duss_hal_obj_handle_t ion_h int compression_dict_size = 0; void *compression_dict = open_dict(DICTIONARY_VERSION, &compression_dict_size); + // VTX Manager + vtx_manager_enabled = get_boolean_config_value(VTX_MPS_CONFIG_KEY); + if(vtx_manager_enabled == true) { + setupVTXManager(); + } + uint64_t event_number; while (!quit) { diff --git a/jni/rec/rec_shim.h b/jni/rec/rec_shim.h index 636831d..09132d7 100644 --- a/jni/rec/rec_shim.h +++ b/jni/rec/rec_shim.h @@ -5649,6 +5649,90 @@ struct __gs_gui_config int (*get_sd_status)(void *, int, uint8_t *, uint32_t *, uint32_t *); int (*play_pwm_buzzer)(void *, int, int, int); int (*buzzer_enable_bat)(void *, _Bool); + int (* gs_ext_fc_get_battery_mah)(void *ctx,uint16_t *mah); + int (* gs_ext_fc_get_battery_usage)(void *ctx,uint16_t *percent); + int (* gs_ext_fc_get_battery_power)(void *ctx,uint16_t *power); + int (* gs_ext_fc_set_arming_disabled)(void *ctx,uint8_t arming_disabled); + int (* gs_ext_fc_get_arming_disabled)(void *ctx,uint32_t *arming_disabled); + int (* gs_ext_fc_get_version)(void *ctx,uint8_t *major,uint8_t *minor,uint8_t *patch_level); + int (* gs_ext_fc_set_sbus_mode)(void *ctx,uint8_t sbus_mode); + int (* gs_ext_fc_get_racing_osd_info)(void *ctx,void *osdInfo);//(void *ctx,DUSS_MSG_FC_RACING_DRONE_OSD_PUSH_t *osdInfo); + int (* gs_ext_fc_get_osd_position)(void *ctx,int num,bool *activated,int *x,int *y); + int (* gs_ext_fc_get_units)(void *ctx,uint8_t *units); + int (* gs_ext_fc_get_fly_mode)(void *ctx,uint16_t *fly_mode); + int (* gs_ext_fc_get_rtc_date)(void *ctx,void *rtc);//(void *ctx,DUSS_MSG_EXT_FC_RTC_t *rtc); + int (* gs_ext_fc_get_esc_temperature)(void *ctx,uint8_t *temp); + void (* dummy_1)(void); + void (* dummy_2)(void); + int (* gs_media_adjust_fov)(void *ctx,uint32_t scaling,int16_t x,int16_t y); + int (* gs_bl_set_brightness_value)(void *ctx,uint8_t value); + int (* gs_bl_get_brightness_value)(void *ctx,uint8_t *value); + void (* get_device_volume)(void); + void (* set_device_volume)(void); + void (* gs_imu_acc_gyro_calibrate)(char *configfile); + void (* gs_imu_initialize)(void); + void (* gs_imu_destroy)(void); + void (* gs_imu_start)(void); + void (* gs_imu_stop)(void); + void (* gs_imu_get_init_status)(void); + void (* gs_imu_get_attitude)(void); + int (* gs_sd_format_wrap)(void *ctx); + int (* gs_sd_get_info_wrap)(void *ctx,void *sd_info);//(void *ctx,gs_local_sd_info_t *sd_info) + int (* gs_get_battery_info)(void *ctx,void *bat_info);//(void *ctx,DUSS_MSG_RC_BAT_INFO_t *bat_info); + int (* gs_get_device_active_state)(void *ctx,int device_type); + int (* gs_av_in_us_get_brightness)(void *ctx,uint8_t *value); + int (* gs_av_in_us_set_brightness)(void *ctx,uint8_t value); + void (* dummy_3)(void); + int (* gs_av_in_us_get_satutation)(void *ctx,uint8_t *value); + int (* gs_av_in_us_set_saturaton)(void *ctx,uint8_t value); + int (* gs_reset_user_settings)(void *ctx); + int (* gs_ui_event_tracking)(void *ctx,int32_t value,uint8_t event_type,uint8_t event_sub_id); + void (* gs_get_real_flight_stat)(uint8_t *stat); + void (* gs_set_flight_stat)(uint8_t stat); + int (* gs_watermarker_us_get_flag)(void *ctx,uint8_t *value); + int (* gs_watermarker_us_set_flag)(void *ctx,uint8_t value); + int (* gs_watermarker_us_reset)(void *ctx); + int (* gs_player_open)(void *ctx,char *filename); + int (* gs_player_close)(void *ctx); + int (* gs_player_stop)(void *ctx); + int (* gs_player_pause)(void *ctx); + int (* gs_player_resume)(void *ctx); + int (* gs_player_seek_time)(void *ctx,uint32_t time); + int (* gs_player_seek)(void *ctx,uint32_t pos); + int (* gs_player_get_duration)(char *filename,uint32_t *duration); + int (* gs_player_get_cur_time)(void *ctx,uint32_t *cur_time,uint32_t *duration); + int (* gs_player_get_state)(void *ctx,uint32_t *state); + int (* gs_player_get_fileinfo)(char *filename,void *file_info);//(char *filename,vdec_video_file_info_t *file_info); + int (* gs_player_is_playing)(void *ctx,bool *is_playing); + int (* gs_player_delete_file)(char *filename); + int (* gs_send_camera_cmd_async)(void *event_obj,int cam_cmd,void *msg,uint32_t msg_len,uint16_t seq_id);//(duss_event_client *event_obj,int cam_cmd,void *msg,uint32_t msg_len,uint16_t seq_ id) + int (* gs_set_camera_param)(void *ctx,uint8_t param_type,uint8_t param); + int (* gs_uav_camera_get_rec_time)(void *ctx,int *mode,int *rec_time); + int (* gs_modem_pairing_control_wrap)(void *ctx,uint32_t ctrl); + void (* dummy_4)(void); + void (* dummy_5)(void); + void (* dummy_6)(void); + void (* dummy_7)(void); + void (* dummy_8)(void); + void (* dummy_9)(void); + void (* dummy_10)(void); + void (* dummy_11)(void); + void (* dummy_12)(void); + void (* dummy_13)(void); + void (* dummy_14)(void); + void (* dummy_15)(void); + void (* dummy_16)(void); + int (* gs_modem_get_link_state_wrap)(void *ctx,gs_link_stat_t *link_stat); + int (* gs_modem_get_bandwidth)(void *ctx,uint16_t *bandwidth); + int (* gs_modem_set_bandwidth)(void *ctx,uint16_t bandwidth); + int (* gs_modem_get_chnl)(void *ctx,uint16_t *chnl_id); + int (* gs_modem_set_chnl_scan_info)(void *ctx,uint8_t chnl_num,uint8_t bandwidth); + int (* gs_modem_rob_chnl_cancel)(void *ctx); + int (* gs_modem_rob_chnl)(void *ctx,uint16_t chnl_id); + int (* gs_modem_get_rob_left_time)(void *ctx,uint8_t *left_time); + int (* gs_modem_get_rob_flag)(void *ctx,uint8_t *flag); + int (* gs_modem_clear_rob_flag)(void *ctx); + int (* gs_modem_set_public_chnl)(void *ctx); }; struct AVCodecParserContext diff --git a/jni/util/fs_util.c b/jni/util/fs_util.c index f1769e0..3570c77 100644 --- a/jni/util/fs_util.c +++ b/jni/util/fs_util.c @@ -34,7 +34,7 @@ void *open_dict(int dict_version, int *size) { size_t filesize = st.st_size; int fd = open(file_path, O_RDONLY, 0); if (!fd) { - return -1; + return (void *)-1; } void* dict = malloc(filesize); void* mmappedData = mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, fd, 0); diff --git a/jni/util/vtx_manager.c b/jni/util/vtx_manager.c new file mode 100644 index 0000000..44c30d3 --- /dev/null +++ b/jni/util/vtx_manager.c @@ -0,0 +1,74 @@ +#include +#include +#include "util/debug.h" +#include "vtx_manager.h" +#include "../rec/rec_shim.h" + + +#define CHANNEL_PUBLIC 8 + +static void *tp1801_gui_lib = NULL; +// static uint32_t (* setChannelPilotOriginal)(void *this,unsigned short param_1, bool param_2) = 0; +// or +static uint32_t (* setChannelPilotOriginal)(uint32_t this, unsigned short param_1, bool param_2) = 0; +static uint32_t (* userSettingsGetInstanceOriginal)() = 0; +static uint32_t userSettingsInstance = 0; +static __gs_gui_config *gs_gui_config = 0; +static int8_t currentChannel = -1; + +void setupVTXManager() { + if(setChannelPilotOriginal != NULL) { + //Already setup + return; + } + + //Load SetPilotChannel original + setChannelPilotOriginal = dlsym (RTLD_NEXT, "_ZN17GlassUserSettings15setPilotChannelEtb"); + if (setChannelPilotOriginal == NULL) { + if(!tp1801_gui_lib){ + tp1801_gui_lib = dlopen("/system/lib/libtp1801_gui.so", 1); + } + setChannelPilotOriginal = dlsym (tp1801_gui_lib, "_ZN17GlassUserSettings15setPilotChannelEtb"); + if (setChannelPilotOriginal == NULL) + { + printf("dlsym: %s\n", dlerror()); + return; + } + } + + //Load UserSettingGetInstance original + userSettingsGetInstanceOriginal = dlsym (tp1801_gui_lib, "_ZN17GlassUserSettings11getInstanceEv"); + if (userSettingsGetInstanceOriginal == NULL) + { + printf("dlsym: %s\n", dlerror()); + return; + } + + userSettingsInstance = userSettingsGetInstanceOriginal(); + if(userSettingsInstance == NULL) { + printf("dlsym: error loading user setting instance"); + return; + } + gs_gui_config = (__gs_gui_config *)*(uint32_t *)((int)userSettingsInstance + 0xe4); +} + +void changeChannel(int8_t channel) { + if (channel <= 0 || channel > 8) { + printf("VTX_MANAGER Error:, invalid channel index: %d\n", channel); + return; + } + + if(currentChannel == channel) { + return; + } + currentChannel = channel; + + DEBUG_PRINT("VTX_MANAGER: requesting to the goggles to set channel %d\n", channel); + + if(channel == CHANNEL_PUBLIC){ + gs_gui_config->gs_modem_set_public_chnl(gs_gui_config->ctx); + } else { + int8_t channelIdx = channel - 1; + setChannelPilotOriginal(userSettingsGetInstanceOriginal(), channelIdx, true); + } +} diff --git a/jni/util/vtx_manager.h b/jni/util/vtx_manager.h new file mode 100644 index 0000000..eaf780a --- /dev/null +++ b/jni/util/vtx_manager.h @@ -0,0 +1,4 @@ +#pragma once + +void setupVTXManager(); +void changeChannel(int8_t channel); \ No newline at end of file