Repository: cmiguelcabral/mjsxj05cm-hacks Branch: dev Commit: 62eda1322188 Files: 41 Total size: 15.6 MB Directory structure: gitextract_jczd0x7e/ ├── .github/ │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .gitmodules ├── README.md ├── build ├── firmware/ │ └── 3.4.2_0062/ │ └── tf_recovery.img └── sdcard/ ├── hacks/ │ ├── framegrabber/ │ │ └── bin/ │ │ ├── .build │ │ └── framegrabber │ ├── motor-control/ │ │ ├── bin/ │ │ │ └── .build │ │ └── meta/ │ │ └── service/ │ │ ├── .enable │ │ └── motor-control │ ├── onvif-server/ │ │ ├── bin/ │ │ │ └── .build │ │ └── meta/ │ │ └── service/ │ │ ├── .enable │ │ └── onvif-server │ ├── rtsp-server/ │ │ ├── bin/ │ │ │ └── .build │ │ ├── config/ │ │ │ └── config.json │ │ └── meta/ │ │ ├── config/ │ │ │ ├── config.json │ │ │ └── config.json.template │ │ └── service/ │ │ ├── framegrabber-mainstream │ │ ├── framegrabber-substream │ │ └── rtsp-server │ ├── runit/ │ │ └── bin/ │ │ └── .build │ ├── sftp-server/ │ │ └── bin/ │ │ └── .build │ ├── ssh-server/ │ │ ├── bin/ │ │ │ └── .build │ │ ├── config/ │ │ │ └── config.json │ │ └── meta/ │ │ ├── config/ │ │ │ ├── config.json │ │ │ └── config.json.template │ │ └── service/ │ │ └── ssh-server │ ├── web-config/ │ │ ├── bin/ │ │ │ └── .build │ │ ├── meta/ │ │ │ └── service/ │ │ │ ├── .enable │ │ │ └── web-config │ │ └── www/ │ │ └── .build │ └── websocket-stream-server/ │ ├── bin/ │ │ └── .build │ └── meta/ │ ├── config/ │ │ └── config.json │ └── service/ │ ├── framegrabber-mainstream │ ├── framegrabber-substream │ └── websocket-stream-server └── manu_test/ ├── configure_services.sh ├── disable_factory_mode.sh ├── entrypoint.sh └── manu.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: push: branches: - '*' env: sourceBranch: ${{ github.ref }} isNightly: ${{ contains(github.ref, 'dev') }} isFinalRelease: ${{ contains(github.ref, 'master') }} jobs: build: runs-on: ubuntu-18.04 steps: - name: Check out source code uses: actions/checkout@v2 # - name: Build # uses: dawidd6/action-ansible-playbook@v2 # with: # playbook: build.yml # directory: ./ # options: | # --extra-vars branch=${{ github.ref }} - name: Build latest if: ${{ env.isNightly == 'true' }} env: THAT_HASH: ${{ secrets.THAT_HASH }} run: chmod +x build && ./build dev - name: Build stable if: ${{ env.isFinalRelease == 'true' }} env: THAT_HASH: ${{ secrets.THAT_HASH }} run: chmod +x build && ./build final - name: Release latest uses: marvinpinto/action-automatic-releases@latest if: env.isNightly == 'true' with: automatic_release_tag: latest-rc files: dist/sdcard.zip prerelease: true repo_token: "${{ secrets.GITHUB_TOKEN }}" title: latest-rc - name: Release stable uses: marvinpinto/action-automatic-releases@latest if: env.isFinalRelease == 'true' with: automatic_release_tag: stable files: dist/sdcard.zip prerelease: false repo_token: "${{ secrets.GITHUB_TOKEN }}" title: stable ================================================ FILE: .gitignore ================================================ *.ini *.xcf dist ================================================ FILE: .gitmodules ================================================ [submodule "submodules/x360h1080p-rtsp-server"] path = submodules/x360h1080p-rtsp-server url = https://github.com/telmomarques/x360h1080p-rtsp-server.git [submodule "submodules/mija-framegrabber"] path = submodules/mija-framegrabber url = https://github.com/crckmc/mija-framegrabber.git [submodule "submodules/x360h1080p-websocket-stream-server"] path = submodules/x360h1080p-websocket-stream-server url = https://github.com/telmomarques/x360h1080p-websocket-stream-server.git [submodule "submodules/x360h1080p-web-config-client"] path = submodules/x360h1080p-web-config-client url = https://github.com/telmomarques/x360h1080p-web-config-client [submodule "submodules/x360h1080p-web-config-server"] path = submodules/x360h1080p-web-config-server url = https://github.com/telmomarques/x360h1080p-web-config-server ================================================ FILE: README.md ================================================ [![discord](https://img.shields.io/discord/713125176971231233?label=discord)](http://discord.gg/qggupzu) Stable: ![CI](https://github.com/cmiguelcabral/mjsxj05cm-hacks/workflows/CI/badge.svg?branch=master) Latest: ![CI](https://github.com/cmiguelcabral/mjsxj05cm-hacks/workflows/CI/badge.svg?tag=latest-rc) # Mi Camera Hacks (MJSXJ05CM) - [Supported Cameras](#supported-cameras) - [Features](#features) - [Install Instructions](#install-instructions) - [FAQ](#faq) - [These Guys are Awesome](#these-guys-are-awesome) Keep calm and follow the procedure! Seriously now: it's still in beta, please read everything before continuing. ## Supported Cameras For now this is it, I'm working on supporting more cameras. Model Name(s) | Picture --- | --- MJSXJ05CM|![MJSXJ05CM](images/MJSXJ02CM.jpg) ## Features Feature | Latest | Stable --- | --- | --- Motor Control | ![C/C++ CI](https://github.com/cmiguelcabral/mjsxj05cm-motor-control/workflows/C/C++%20CI/badge.svg?tag=latest-rc) | ![C/C++ CI](https://github.com/cmiguelcabral/mjsxj05cm-motor-control/workflows/C/C++%20CI/badge.svg?branch=master) Onvif Server | ![C/C++ CI](https://github.com/cmiguelcabral/mjsxj05cm-onvif_srvd/workflows/C/C++%20CI/badge.svg?tag=latest-rc) | ![C/C++ CI](https://github.com/cmiguelcabral/mjsxj05cm-onvif_srvd/workflows/C/C++%20CI/badge.svg?branch=master) RTSP Server | ![C/C++ CI](https://github.com/cmiguelcabral/mjsxj05cm-rtsp-server/workflows/C/C++%20CI/badge.svg?tag=latest-rc)| ![C/C++ CI](https://github.com/cmiguelcabral/mjsxj05cm-rtsp-server/workflows/C/C++%20CI/badge.svg?branch=master) Runit | ![C/C++ CI](https://github.com/telmomarques/runit/workflows/C/C++%20CI/badge.svg?tag=latest-rc) | ![C/C++ CI](https://github.com/telmomarques/runit/workflows/C/C++%20CI/badge.svg?branch=master) SFTP Server | ![C/C++ CI](https://github.com/telmomarques/openssh-portable/workflows/C/C++%20CI/badge.svg?tag=latest-rc) | ![C/C++ CI](https://github.com/telmomarques/openssh-portable/workflows/C/C++%20CI/badge.svg?branch=master) SSH Server |![C/C++ CI](https://github.com/telmomarques/dropbear/workflows/C/C++%20CI/badge.svg?tag=latest-rc)|![C/C++ CI](https://github.com/telmomarques/dropbear/workflows/C/C++%20CI/badge.svg?branch=master) Web Configuration Client | ![Node.js CI](https://github.com/cmiguelcabral/mjsxj05cm-web-client/workflows/Node.js%20CI/badge.svg?tag=latest-rc) | ![Node.js CI](https://github.com/cmiguelcabral/mjsxj05cm-web-client/workflows/Node.js%20CI/badge.svg?branch=master) Web Configuration Server | ![Go](https://github.com/cmiguelcabral/mjsxj05cm-web-server/workflows/Go/badge.svg?tag=latest-rc)| ![Go](https://github.com/cmiguelcabral/mjsxj05cm-web-server/workflows/Go/badge.svg?branch=master) Websocker Stream Server | ![Go](https://github.com/cmiguelcabral/mjsxj05cm-websocket-stream-server/workflows/Go/badge.svg?tag=latest-rc)| ![Go](https://github.com/cmiguelcabral/mjsxj05cm-websocket-stream-server/workflows/Go/badge.svg?branch=master) ## Install Instructions The hacks exploits a flaw in firmware version 3.4.2_0062, **please read the instructions very carefully!!** - First [Check your camera firmware version](#view-camera-firmware-version) - If you have firmware version 3.4.2_0062, go to [Install the hacks](#install-the-hacks) - If you have another firmware version, nothing can be done unfortunately. ### View camera firmware version 1. Configure the camera using the Mi Home app 2. Open the camera in the app and touch the 3 dots in the upper right corner 3. Select the option "General Settings", and then "Check for firmware upgrades" 4. The current firmware version is presented on the screen ### Downgrade the Firmware ⚠️ It is not possible to downgrade the frimware to 3.4.2_0062 on the MJSXJ05CM If you have try to use an firmware and you camera is stuck on amber light try [this firmware](https://drive.google.com/file/d/1ve6XlBEiZebJV6ukJ0Oiu7DePw2JCsWj/view) ### Install the hacks 1. Configure the camera using the Mi Home app 2. Download the latest release from [releases](https://github.com/telmomarques/xiaomi-360-1080p-hacks/releases) 3. Copy the **contents** of "sdcard" folder to the root of your SD Card 4. Power off the camera and insert the SD Card 5. Power on the camera 6. Find the IP address of your camera 7. Open the web config interface o the camrea on your browser: [http://&1 | grep -c 'HTTP/1.1 200 OK') if [ $is_200_ok != "1" ]; then echo "Failed to get ${assetName}" exit 1 fi } download_from_url() { local assetName=$1 is_200_ok=$(wget -q --show-progress --server-response ${1} 2>&1 | grep -c 'HTTP/1.1 200 OK') if [ $is_200_ok != "1" ]; then echo "Failed to get ${assetName}" exit 1 fi } process_external_download() { local url=$1 local filename=$2 echo Downloading \"${url}\" download_from_url ${url} } process_github_release_asset_download() { local owner=$1 local repository=$2 local assetName=$3 if [ $releaseType == "dev" ]; then tagName="latest-rc" fi if [ $releaseType == "final" ]; then tagName="latest" fi echo Downloading \"${owner}/${repository}@${tagName}/${assetName}\" github_download_release_asset ${owner} ${repository} ${tagName} ${assetName} } extract() { local fileName=${1} case "$fileName" in *.zip) echo Extracting ${fileName} extract_zip ${fileName} rm -f ${assetFilename} ;; *.tar) echo Extracting ${fileName} extract_tar ${fileName} rm -f ${assetFilename} ;; esac } extract_zip() { unzip -qq ${1} } extract_tar() { tar -xf ${1} } process_build_file() { local buildType=$1 local buildFilePath=.build local source=$(cat ${buildFilePath} | jq -r ".source") local assetFilename="" if [ "${source}" == "external" ]; then local url=$(cat ${buildFilePath} | jq -r ".url") assetFilename=$(cat ${buildFilePath} | jq -r ".filename") process_external_download ${url} ${assetFilename} elif [ "${source}" == "github-release-asset" ]; then local owner=$(cat ${buildFilePath} | jq -r ".owner") local repository=$(cat ${buildFilePath} | jq -r ".repository") assetFilename=$(cat ${buildFilePath} | jq -r ".assetName") process_github_release_asset_download ${owner} ${repository} ${assetFilename} fi rm $buildFilePath if [[ ! -z ${assetFilename} ]]; then extract ${assetFilename} fi if [ -d "uclibc" ]; then cp uclibc/* . rm -rf libc uclibc fi } clean() { echo "Cleaning..." rm -rf dist } build() { echo "Building..." test -d dist || mkdir dist cp -r sdcard/* dist/ shopt -s globstar for buildFile in dist/**/.build; do pushd $(dirname ${buildFile}) process_build_file ${1} popd done } package() { pushd dist zip -r sdcard.zip * -x hacks/**/libc -x hacks/**/uclibc popd } main() { local target=$1 case ${target} in clean) clean ;; dev | rc | final) releaseType=$1 clean build package ;; *) echo "Invalid target '${1}'" ;; esac } main $1 ================================================ FILE: firmware/3.4.2_0062/tf_recovery.img ================================================ [File too large to display: 15.6 MB] ================================================ FILE: sdcard/hacks/framegrabber/bin/.build ================================================ { "source": "github-release-asset", "owner": "telmomarques", "repository": "mija-framegrabber", "assetName": "framegrabber.zip", "clean": [ "ipc009" ] } ================================================ FILE: sdcard/hacks/framegrabber/bin/framegrabber ================================================ #!/bin/sh CAMERA_MODEL=`factory get model | cut -d '.' -f3` if [ -z "$CAMERA_MODEL" ]; then echo "Can't get camera model, exiting." exit 1 fi BINARY_PATH=${CAMERA_MODEL}/framegrabber if [ ! -f "$BINARY_PATH" ]; then echo "Camera model '${CAMERA_MODEL}' not supported, exiting." exit 1 fi cp -f ${BINARY_PATH} /mnt/data/bin exec /mnt/data/bin/framegrabber "$@" ================================================ FILE: sdcard/hacks/motor-control/bin/.build ================================================ { "source": "github-release-asset", "owner": "cmiguelcabral", "repository": "mjsxj05cm-motor-control", "assetName": "motord" } ================================================ FILE: sdcard/hacks/motor-control/meta/service/.enable ================================================ ================================================ FILE: sdcard/hacks/motor-control/meta/service/motor-control ================================================ #!/bin/sh cd /mnt/sdcard/hacks/motor-control/bin exec ./motord ================================================ FILE: sdcard/hacks/onvif-server/bin/.build ================================================ { "source": "github-release-asset", "owner": "cmiguelcabral", "repository": "mjsxj05cm-onvif_srvd", "assetName": "onvif_srvd" } ================================================ FILE: sdcard/hacks/onvif-server/meta/service/.enable ================================================ ================================================ FILE: sdcard/hacks/onvif-server/meta/service/onvif-server ================================================ #!/bin/sh cd /mnt/sdcard/hacks/onvif-server/bin source /mnt/data/etc/os-release STEPS=5 MOTOR_CONTROL="/mnt/sdcard/hacks/motor-control/bin" EVENT_FILE="$MOTOR_CONTROL/event" LEFT="echo pan forward $STEPS > $EVENT_FILE" RIGHT="echo pan reverse $STEPS > $EVENT_FILE" UP="echo tilt forward $STEPS > $EVENT_FILE" DOWN="echo tilt reverse $STEPS > $EVENT_FILE" IP_ADDR=$(ip -4 addr show wlan0 | grep inet | awk '{print $2}' | cut -d'/' -f1) while [[ -z $IP_ADDR ]]; do IP_ADDR=$(ip -4 addr show wlan0 | grep inet | awk '{print $2}' | cut -d'/' -f1) done echo $IP_ADDR ONVIF_PROFILE_0="--name HD --width 1920 --height 1080 --url rtsp://$IP_ADDR:8554/mainstream --type H264" ONVID_PROFILE_1="--name SD --width 640 --height 360 --url rtsp://$IP_ADDR:8554/substream --type H264" echo $ONVIF_PROFILE_0 echo $ONVIF_PROFILE_1 exec ./onvif_srvd --no_fork --pid_file /var/run/onvif_srvd.pid --model "MJSXJ05CM" --manufacturer "Xiaomi" --ifs wlan0 --port 5000 --scope onvif://www.onvif.org/Profile/S $ONVIF_PROFILE_0 $ONVIF_PROFILE_1 \ --ptz \ --move_left "eval $LEFT" \ --move_right "eval $RIGHT" \ --move_up "eval $UP" \ --move_down "eval $DOWN" ================================================ FILE: sdcard/hacks/rtsp-server/bin/.build ================================================ { "source": "github-release-asset", "owner": "cmiguelcabral", "repository": "mjsxj05cm-rtsp-server", "assetName": "rtspserver" } ================================================ FILE: sdcard/hacks/rtsp-server/config/config.json ================================================ { "encodingType": "h265" } ================================================ FILE: sdcard/hacks/rtsp-server/meta/config/config.json ================================================ { "enable": false, "encodingType": "h265" } ================================================ FILE: sdcard/hacks/rtsp-server/meta/config/config.json.template ================================================ { "encodingType": "{{.EncodingType}}" } ================================================ FILE: sdcard/hacks/rtsp-server/meta/service/framegrabber-mainstream ================================================ #!/bin/sh ETCDIR=/mnt/data/etc/framegrabber/ RTSP_MAINSTREAM_PIPE="${ETCDIR}rtsp_mainstream" mkdir -p $ETCDIR mkfifo $RTSP_MAINSTREAM_PIPE cd /mnt/sdcard/hacks/framegrabber/bin exec ./framegrabber -f $RTSP_MAINSTREAM_PIPE -c 0 ================================================ FILE: sdcard/hacks/rtsp-server/meta/service/framegrabber-substream ================================================ #!/bin/sh ETCDIR=/mnt/data/etc/framegrabber/ RTSP_SUBSTREAM_PIPE="${ETCDIR}rtsp_substream" mkdir -p $ETCDIR mkfifo $RTSP_SUBSTREAM_PIPE cd /mnt/sdcard/hacks/framegrabber/bin exec ./framegrabber -f $RTSP_SUBSTREAM_PIPE -c 1 ================================================ FILE: sdcard/hacks/rtsp-server/meta/service/rtsp-server ================================================ #!/bin/sh cd /mnt/sdcard/hacks/rtsp-server/bin cp -f rtspserver /mnt/data/bin exec /mnt/data/bin/rtspserver -c ../config/config.json -m /mnt/data/etc/framegrabber/rtsp_mainstream -s /mnt/data/etc/framegrabber/rtsp_substream ================================================ FILE: sdcard/hacks/runit/bin/.build ================================================ { "source": "github-release-asset", "owner": "cmiguelcabral", "repository": "mjsxj05cm-runit", "assetName": "runit.tar", "clean": [ "*" ] } ================================================ FILE: sdcard/hacks/sftp-server/bin/.build ================================================ { "source": "github-release-asset", "owner": "telmomarques", "repository": "openssh-portable", "assetName": "sftp-server.tar" } ================================================ FILE: sdcard/hacks/ssh-server/bin/.build ================================================ { "source": "github-release-asset", "owner": "telmomarques", "repository": "dropbear", "assetName": "dropbear.tar" } ================================================ FILE: sdcard/hacks/ssh-server/config/config.json ================================================ { "users": [ ] } ================================================ FILE: sdcard/hacks/ssh-server/meta/config/config.json ================================================ { "enable": false, "users": [] } ================================================ FILE: sdcard/hacks/ssh-server/meta/config/config.json.template ================================================ { "users": [ {{range $i, $u := .Users}} {{if $i}}, {{end}} {"systemUsername": "{{.SystemUsername}}", "username": "{{.Username}}", "password": "{{.Password}}"} {{end}} ] } ================================================ FILE: sdcard/hacks/ssh-server/meta/service/ssh-server ================================================ #!/bin/sh mkdir -p /mnt/data/etc/dropbear cd /mnt/sdcard/hacks/ssh-server/bin exec ./dropbear -FERB ================================================ FILE: sdcard/hacks/web-config/bin/.build ================================================ { "source": "github-release-asset", "owner": "cmiguelcabral", "repository": "mjsxj05cm-web-server", "assetName": "web-config-server" } ================================================ FILE: sdcard/hacks/web-config/meta/service/.enable ================================================ ================================================ FILE: sdcard/hacks/web-config/meta/service/web-config ================================================ #!/bin/sh cd /mnt/sdcard/hacks/web-config/bin exec ./web-config-server ================================================ FILE: sdcard/hacks/web-config/www/.build ================================================ { "source": "github-release-asset", "owner": "cmiguelcabral", "repository": "mjsxj05cm-web-client", "assetName": "web-config-client.zip", "clean": [ "*" ] } ================================================ FILE: sdcard/hacks/websocket-stream-server/bin/.build ================================================ { "source": "github-release-asset", "owner": "telmomarques", "repository": "x360h1080p-websocket-stream-server", "assetName": "websocket-stream-server" } ================================================ FILE: sdcard/hacks/websocket-stream-server/meta/config/config.json ================================================ { "enable": false } ================================================ FILE: sdcard/hacks/websocket-stream-server/meta/service/framegrabber-mainstream ================================================ #!/bin/sh ETCDIR=/mnt/data/etc/framegrabber/ WEBSOCKET_MAINSTREAM_PIPE="${ETCDIR}websocket_mainstream" mkdir -p $ETCDIR mkfifo $WEBSOCKET_MAINSTREAM_PIPE cd /mnt/sdcard/hacks/framegrabber/bin exec ./framegrabber -f $WEBSOCKET_MAINSTREAM_PIPE -c 0 ================================================ FILE: sdcard/hacks/websocket-stream-server/meta/service/framegrabber-substream ================================================ #!/bin/sh ETCDIR=/mnt/data/etc/framegrabber/ WEBSOCKET_SUBSTREAM_PIPE="${ETCDIR}websocket_substream" mkdir -p $ETCDIR mkfifo $WEBSOCKET_SUBSTREAM_PIPE cd /mnt/sdcard/hacks/framegrabber/bin exec ./framegrabber -f $WEBSOCKET_SUBSTREAM_PIPE -c 1 ================================================ FILE: sdcard/hacks/websocket-stream-server/meta/service/websocket-stream-server ================================================ #!/bin/sh cd /mnt/sdcard/hacks/websocket-stream-server/bin/ exec ./websocket-stream-server -m=/mnt/data/etc/framegrabber/websocket_mainstream -s=/mnt/data/etc/framegrabber/websocket_substream ================================================ FILE: sdcard/manu_test/configure_services.sh ================================================ #!/bin/sh HACKS_DIR=/mnt/sdcard/hacks SERVICES_DIR=/mnt/data/etc/runit install_service() { hackName=$1 serviceDir=${HACKS_DIR}/${hackName}/meta/service if [ -d ${serviceDir} ] && [ -f ${serviceDir}/.enable ]; then cd ${serviceDir} for service in ${serviceDir}/* ; do serviceName=`basename ${service}` hackServiceDir=${SERVICES_DIR}/${hackName}-${serviceName} mkdir -p ${hackServiceDir} cp ${service} ${hackServiceDir}/run done fi } install_services() { rm -rf ${SERVICES_DIR} for hack in ${HACKS_DIR}/* ; do if [ -d ${hack} ]; then hackName=`basename $hack` install_service ${hackName} fi done; export PATH=$PATH:${HACKS_DIR}/runit/bin runsvdir ${SERVICES_DIR} & } if [ -z $1 ]; then install_services else install_service $1 fi ================================================ FILE: sdcard/manu_test/disable_factory_mode.sh ================================================ #!/bin/sh if [ -f "/tmp/factory_mode" ]; then rm -f /tmp/factory_mode else echo '#!/bin/sh rm -- "$0"' > /mnt/data/bin/touch chmod +x /mnt/data/bin/touch fi ================================================ FILE: sdcard/manu_test/entrypoint.sh ================================================ #!/bin/sh echo "Xiaomi Hacks enabled" /mnt/sdcard/manu_test/disable_factory_mode.sh /mnt/sdcard/manu_test/configure_services.sh & ================================================ FILE: sdcard/manu_test/manu.sh ================================================ #!/bin/sh /mnt/sdcard/manu_test/entrypoint.sh