SAIC-iSmart-API / reverse-engineering

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Contributors Forks Stargazers Issues MIT License


SAIC-API Documentation (MG iSmart/iSmart lite)

We try to understand how the SAIC-API used by MG cars (MG5 EV, MG ZSV...) works and how we can interact with it.
Explore the docs »

Current state · Report Bug · Request Feature

About The Project

The project consists of the readme, some sample Python code and the ASN.1 schemas. With this project we try to get rid of the slow and complicated iSmart-Application on iOS and Android.

If we completely understand the API we can start to build adapters for projects like Sonne tanken and a integration for Home Assistant.

What's working:

What's in progress:

  • Understanding the ASN.1 post response for vehicleStatus.
  • Extracting ASN.1 schema for ota.mpv30

To-Do:

  • Get SOC state of vehicle
  • Get GPS position
  • Login via post requests

(back to top)

Getting Started

If you want to start debugging and exploring the API (and you do not have an access token) you need:

It consists of two steps:

  • Step 1: Collect API sample response from the iSmart application with android studio and mitmproxy
  • Step 2: Try to decode the post response with the sample python code

android studio and mitmproxy

Use android studio to emulate the iSmart application and collect the api calls with mitmproxy. Inspired by this medium article

  1. Download and install and install android studio
  2. Create a Android virtual device (AVD) in android studio (working combination)
    Pixel 5 API 23
    Android 6.0 armeabi-v7a (custom certificates only work until android 6.0!)
    increase interal storage to 2GB
    
  3. Uncheck "Launch in tool window" in android studio (File->Settings->Tools->Emulator)
  4. Launch AVD (will take 5-10 minutes, slow emulation)
  5. Download iSmart APK
  6. Install iSmart APK via ADB (will take 10-20 minutes)
.\adb.exe install "path\to\iSmart.apk"
  1. Open AVD configuration window and set proxy settings (according to your own desktop IP) AVD Config

  2. Install mitmproxy certificate by browsing to mitm.it on the emulated android device.

  3. Download and install and install mitmproxy

  4. Launch mitmproxy and start collecting API requests of the emulated android device and iSmart application SAIC-API requests

python sample code

The python sample code tries to decode the ASN.1 iSmart post responses collected by mitmproxy.

  1. Install asn1tools with pip
    pip install asn1tools
  2. Refresh the main screen of the iSmart app and copy the API response from mitmproxy into the file /src/response.per
  3. Run /src/decodeSampleResponse.py
  4. Experiment with the ASN.1 schema and try to understand and decode it

(back to top)

API Documentation

This will be extended in the following days. WIP!

Two endpoints are used:

Vehicle SAIC OTA Endpoint

The android app requests sends the following two requests if the main screen is refreshed:

This endpoint is used to communicate with the vehicle API. The response data needs to be converted to Hex and can be used in the python code sample. See Step 2

The response seems to be containing vehicleData, SOC, GPS position, locking state, driving state.... encoded in ASN.1 with PER. ASN.1 schema

Request 1:

The RAW-Body consists of ASN.1 data (WIP not sure what it contains, access tokens? passwords?)

POST https://tap-eu.soimt.com/TAP.Web/ota.mpv21 HTTP/1.1
Content-Length: 269
Content-Type: text/html
Host: tap-eu.soimt.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
RAW-Body: 10087217300...(truncated user data/privacy)......00465014002 
Curl command curl -H 'Content-Type: text/html' -H 'Host: tap-eu.soimt.com' -H 'Connection: Keep-Alive' -H 'User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)' -X POST https://tap-eu.soimt.com/TAP.Web/ota.mpv21 -d 1008720...(truncated user data/privacy)......465014002

Response 1:

HTTP/1.1 200 
Date: Wed, 28 Sep 2022 10:21:18 GMT
Content-Type: text/html;charset=iso-8859-1
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: JSESSIONID=9FD...(truncated user data/privacy)..7083F; Path=/TAP.Web; HttpOnly
out_timestamp: 1664360478431
RAW-Body (270 symbols): 100882175...(truncated user data/privacy)..00006501400000

Request 2:

Same as Request 1 but with slighty changed RAW-Body.

Response 2:

HTTP/1.1 200 
Date: Wed, 28 Sep 2022 10:21:19 GMT
Content-Type: text/html;charset=iso-8859-1
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: JSESSIONID=455F97...(truncated user data/privacy).72AE; Path=/TAP.Web; HttpOnly
out_timestamp: 1664360479271
RAW-Body (670 symbols): 1014F21750031...(truncated user data/privacy)..004000

SAIC gateway

This endpoint is used to register a account (access tokens?), to accept account GDPR and get app specific data (timezone, country list).

Example timezone request:

GET https://gateway-eu.soimt.com/api.app/v1/user/timezone HTTP/1.1
APP-LANGUAGE-TYPE: en
APP-USER-ID: 00000000000000000000000000.(truncated user data/privacy)002
APP-SEND-DATE: 1664360420536
Content-Type: application/json;charset=UTF-8
APP-CONTENT-ENCRYPTED: 0
APP-LOGIN-TOKEN: 06f4...(truncated user data/privacy)..210e0
Host: gateway-eu.soimt.com
Connection: Keep-Alive
No content

Example timezone response:

HTTP/1.1 200 
Date: Wed, 28 Sep 2022 10:20:21 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
JSON
  
{
    "code": 0,
    "data": {
        "timezone": "GMT+00:00"
    },
    "message": "success"
}

(back to top)

ASN.1 schema

The ASN.1 schema provided by the source APK seems to be an old version of the protocol. It is not possible to decode the API response without the correct ASN.1 schema. See (issue 1) [ReverseEngineeringDE/SAIC-API-Documentation#1]

There are several versions of the binary protocol which can be found in the source of the APK (com.saicmotor.telematics.tsgp.otaadapter.mp). They all have different API endpoints according to their version number.

asn1extractor

The helper tool built by @tisoft automatically generates ASN.1 schema files from the annotated classes of the APK. Take a look at the asn1extrator readme to understand how it works.

v3_0 Endpoint (ota.mpv30)

V3.0 seems to be the first version which features entities used by electric vehicles (RvsChargingStatus.java). The ota.mpv30 endpoint only gets called on the "Charging Management"-page of the mobile application. A ASN.1 schema needs to be built.

Caveats

ASN.1 schema decoded outputs with asn1tools are weird?

Values are not correct

Decoded values with the ASN.1 schema and the python asn1tools do not make sense. In the following example the gpsPosition is wrong. Altitude should be a three digit number but has five digits (according to ASN.1 schema; --altitude,UNIT:meter).

# decode VehicleStatusResp with asn1tools
VehicleStatusResp = asn1Tool.decode('VehicleStatusResp', byteArray)

# values do not make sense at all? vehicleData can not be converted? 
# {'vehicleStatus': {'gpsPosition': {'wayPoint': {'position': {'latitude': -89999952, 'longitude': -179999948, 'altitude': 17870}, 'heading': 12599, 'speed': 12616}, 'timestamp': {'seconds': 51}, 'gpsStatus': 'noGpsSignal'}, 'vehicleData': b'53736323930363636313638383433F0F983060C183060C18306'}}
print("\nVehicleStatusResp:")
print (VehicleStatusResp)

vehicleData contains SOC

vehicleData seems to contain SOC data but can not be decoded? (would be really nice to decode this!!)

{'vehicleData': b'53736323930363636313638383433F0F983060C183060C18306'}

Roadmap

  • TBD

See the open issues for a full list of proposed features (and known issues).

(back to top)

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

License

Distributed under the MIT License. See LICENSE.txt for more information.

The usage of the MG iSmart System is covered by their EULA.

Section 6 (Version: 10.2021) states:

RESTRICTIONS: You are prohibited from renting, lending, public presentation, performance or broadcasting or any other kind of distribution of the Services. You will not, and you will not allow any person to, copy or modify the Services or any part thereof or to reverse engineer, decompile or disassemble the Services except as indispensable to install the App on your end device and to obtain the information necessary to establish the interoperability with an independently created computer programme. You may not use the Services in connection with any illegal, fraudulent, dishonest, unethical activity or behaviour and/or use the Services to store or transmit malicious code, interfere with the integrity or performance of the Services or attempt to gain unauthorised access to the Services and/or any systems or networks connected thereto. You shall keep your login credentials unavailable to others, except vis-a-vis your representatives which use the Services on behalf of you as Represented Party.

This project aims to obtain the information necessary to establish the interoperability with an independently created computer programme and is therefore allowed under the terms of the EULA.

(back to top)

Contact

Author: ReverseEngineeringDE

Project Link: https://github.com/ReverseEngineeringDE/SAIC-API-Documentation

German forum: https://www.goingelectric.de/forum/viewtopic.php?f=612&t=81635

(back to top)

Acknowledgments

(back to top)

About

License:MIT License


Languages

Language:Java 98.0%Language:Shell 2.0%