mirror of https://github.com/commaai/panda.git
Deprecate ESP (#592)
* remove unused wifi tests * remove that one too * no bootmode from ESP * clean that up * remove two more wifi tests * remove boardesp and esptool * esp_gps -> gps * missed those * remove esptool refs * remove esp certs * no more wifi * that was old * cleanup jenkins dockerfile * fix linter * remove more wifi refs * clone panda jungle from github * no copy * always default esp to off
This commit is contained in:
parent
6ae6221cf2
commit
8b41ed3b81
|
@ -1,3 +1,2 @@
|
|||
.git
|
||||
.DS_Store
|
||||
boardesp/esp-open-sdk
|
||||
|
|
|
@ -45,26 +45,6 @@ jobs:
|
|||
- name: Build pedal STM bootstub image
|
||||
run: $RUN "cd /tmp/openpilot/panda/board/pedal && make obj/bootstub.bin"
|
||||
|
||||
build_esp:
|
||||
name: build esp
|
||||
runs-on: ubuntu-16.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build docker image
|
||||
run: |
|
||||
docker pull $(grep -ioP '(?<=^from)\s+\S+' tests/build/Dockerfile.panda_esp) || true
|
||||
docker pull docker.io/commaai/panda_esp:latest || true
|
||||
docker build --cache-from docker.io/commaai/panda_esp:latest -t panda_esp -f tests/build/Dockerfile.panda_esp .
|
||||
- name: Build ESP image
|
||||
run: docker run --rm panda_esp /bin/sh -c "cd /panda/boardesp && make user1.bin"
|
||||
- name: Push image
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/panda'
|
||||
run: |
|
||||
docker login -u wmelching -p ${{ secrets.COMMA_DOCKERHUB_TOKEN }}
|
||||
docker tag panda_esp docker.io/commaai/panda_esp:latest
|
||||
docker push docker.io/commaai/panda_esp:latest
|
||||
|
||||
safety:
|
||||
name: safety
|
||||
runs-on: ubuntu-16.04
|
||||
|
|
|
@ -18,7 +18,7 @@ repos:
|
|||
exclude: '^(tests/automated)/'
|
||||
args:
|
||||
- --select=F,E112,E113,E304,E501,E502,E701,E702,E703,E71,E72,E731,W191,W6
|
||||
- --exclude=python/esptool.py,tests/gmbitbang/*
|
||||
- --exclude=tests/gmbitbang/*
|
||||
- --max-line-length=160
|
||||
- --statistics
|
||||
- repo: local
|
||||
|
|
13
Dockerfile
13
Dockerfile
|
@ -54,7 +54,6 @@ RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-instal
|
|||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv install 2.7.12
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
|
@ -68,16 +67,6 @@ ENV HOME /home/batman
|
|||
|
||||
ENV PYTHONPATH /tmp:$PYTHONPATH
|
||||
|
||||
COPY ./boardesp/get_sdk_ci.sh /tmp/panda/boardesp/
|
||||
COPY ./boardesp/python2_make.py /tmp/panda/boardesp/
|
||||
|
||||
COPY ./panda_jungle /tmp/panda_jungle
|
||||
|
||||
RUN useradd --system -s /sbin/nologin pandauser
|
||||
RUN mkdir -p /tmp/panda/boardesp/esp-open-sdk
|
||||
RUN chown pandauser /tmp/panda/boardesp/esp-open-sdk
|
||||
USER pandauser
|
||||
RUN cd /tmp/panda/boardesp && ./get_sdk_ci.sh
|
||||
USER root
|
||||
RUN cd /tmp && git clone https://github.com/commaai/panda_jungle.git
|
||||
|
||||
ADD ./panda.tar.gz /tmp/panda
|
||||
|
|
|
@ -14,24 +14,19 @@ pipeline {
|
|||
steps {
|
||||
timeout(time: 60, unit: 'MINUTES') {
|
||||
script {
|
||||
try {
|
||||
sh 'cp -R /home/batman/panda_jungle .'
|
||||
} catch (err) {
|
||||
echo "Folder already exists"
|
||||
}
|
||||
sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD'
|
||||
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Test Dev Build (no WIFI)') {
|
||||
stage('Test Dev Build') {
|
||||
steps {
|
||||
lock(resource: "Pandas", inversePrecedence: true, quantity: 1){
|
||||
timeout(time: 60, unit: 'MINUTES') {
|
||||
script {
|
||||
sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'cd /tmp/panda; SKIPWIFI=1 ./run_automated_tests.sh'"
|
||||
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_dev_nowifi.xml"
|
||||
sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'cd /tmp/panda; ./run_automated_tests.sh'"
|
||||
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_dev.xml"
|
||||
sh "docker rm ${env.DOCKER_NAME}"
|
||||
}
|
||||
}
|
||||
|
@ -51,21 +46,6 @@ pipeline {
|
|||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
stage('Test Dev Build (WIFI)') {
|
||||
steps {
|
||||
lock(resource: "Pandas", inversePrecedence: true, quantity: 1){
|
||||
timeout(time: 60, unit: 'MINUTES') {
|
||||
script {
|
||||
sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'cd /tmp/panda; ./run_automated_tests.sh'"
|
||||
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_dev.xml"
|
||||
sh "docker rm ${env.DOCKER_NAME}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
post {
|
||||
failure {
|
||||
|
|
19
README.md
19
README.md
|
@ -6,9 +6,9 @@
|
|||
|
||||
<img src="https://github.com/commaai/panda/blob/master/buy.png"></a>
|
||||
|
||||
It supports 3x CAN, 2x LIN, and 1x GMLAN. It also charges a phone. On the computer side, it has both USB and Wi-Fi.
|
||||
It supports 3x CAN, 2x LIN, and 1x GMLAN. It also charges a phone. On the computer side, it has USB.
|
||||
|
||||
It uses an [STM32F413](http://www.st.com/en/microcontrollers/stm32f413-423.html?querycriteria=productId=LN2004) for low level stuff and an [ESP8266](https://en.wikipedia.org/wiki/ESP8266) for Wi-Fi. They are connected over high speed SPI, so the panda is actually capable of dumping the full contents of the busses over Wi-Fi, unlike every other dongle on amazon. ELM327 is weak, panda is strong.
|
||||
It uses an [STM32F413](http://www.st.com/en/microcontrollers/stm32f413-423.html?querycriteria=productId=LN2004).
|
||||
|
||||
It is 2nd gen hardware, reusing code and parts from the [NEO](https://github.com/commaai/neo) interface board.
|
||||
|
||||
|
@ -56,30 +56,23 @@ As a universal car interface, it should support every reasonable software interf
|
|||
|
||||
- [User space](https://github.com/commaai/panda/tree/master/python)
|
||||
- [socketcan in kernel](https://github.com/commaai/panda/tree/master/drivers/linux) (alpha)
|
||||
- [ELM327](https://github.com/commaai/panda/blob/master/boardesp/elm327.c)
|
||||
- [Windows J2534](https://github.com/commaai/panda/tree/master/drivers/windows)
|
||||
|
||||
## Directory structure
|
||||
|
||||
- board -- Code that runs on the STM32
|
||||
- boardesp -- Code that runs on the ESP8266
|
||||
- drivers -- Drivers (not needed for use with python)
|
||||
- python -- Python userspace library for interfacing with the panda
|
||||
- tests -- Tests and helper programs for panda
|
||||
|
||||
## Programming over USB
|
||||
|
||||
[Programming the Board (STM32)](board/README.md)
|
||||
|
||||
[Programming the ESP](boardesp/README.md)
|
||||
## Programming
|
||||
|
||||
See `board/README.md`
|
||||
|
||||
## Debugging
|
||||
|
||||
To print out the serial console from the STM32, run `tests/debug_console.py`
|
||||
|
||||
To print out the serial console from the ESP8266, run `PORT=1 tests/debug_console.py`
|
||||
|
||||
## Safety Model
|
||||
|
||||
When a panda powers up, by default it's in `SAFETY_SILENT` mode. While in `SAFETY_SILENT` mode, the buses are also forced to be silent. In order to send messages, you have to select a safety mode. Currently, setting safety modes is only supported over USB. Some of safety modes (for example `SAFETY_ALLOUTPUT`) are disabled in release firmwares. In order to use them, compile and flash your own build.
|
||||
|
@ -100,8 +93,8 @@ These are the [CI regression tests](https://github.com/commaai/panda/actions) we
|
|||
* A recorded drive for each supported car variant is [replayed through the safety logic](https://github.com/commaai/panda/tree/master/tests/safety_replay)
|
||||
to ensure that the behavior remains unchanged.
|
||||
* An internal Hardware-in-the-loop test, which currently only runs on pull requests opened by comma.ai's organization members, verifies the following functionalities:
|
||||
* compiling the code in various configuration and flashing it both through USB and WiFi.
|
||||
* Receiving, sending and forwarding CAN messages on all buses, over USB and WiFi.
|
||||
* compiling the code in various configuration and flashing it both through USB.
|
||||
* Receiving, sending and forwarding CAN messages on all buses, over USB.
|
||||
|
||||
In addition, we run the [pylint](https://www.pylint.org/) and [flake8](https://github.com/PyCQA/flake8) linters on all python files within the panda repo.
|
||||
|
||||
|
|
31
TODO
31
TODO
|
@ -1,31 +0,0 @@
|
|||
** Projects **
|
||||
|
||||
== ELM327 Emulator ==
|
||||
|
||||
Write an elm327 emulator in boardesp/elm327.c and make it work with Torque
|
||||
|
||||
You'll find a start at this in the "elm327" branch.
|
||||
|
||||
== socketcan Kernel Driver ==
|
||||
|
||||
Write a kernel driver version of lib/panda.py that exposes the Panda on socketcan and makes it work with those tools.
|
||||
|
||||
You may want to switch to interrupt endpoint first. Should LIN be exposed as a serial interface?
|
||||
|
||||
== Windows J2534 DLL ==
|
||||
|
||||
Write a Windows DLL that exposes the J2534 API.
|
||||
|
||||
Will make the Panda work with car diagnostic software.
|
||||
|
||||
|
||||
** Refactors **
|
||||
|
||||
== USB Interrupt Endpoint ==
|
||||
|
||||
Switch USB to use an interrupt endpoint instead of a bulk endpoint for can recv
|
||||
|
||||
== WebSocket Support ==
|
||||
|
||||
Add CAN streaming over WebSocket to the ELM code in addition to the UDP pipe.
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
# flake8: noqa
|
||||
# pylint: skip-file
|
||||
from .python import Panda, PandaWifiStreaming, PandaDFU, ESPROM, CesantaFlasher, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial
|
||||
from .python import Panda, PandaWifiStreaming, PandaDFU, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial
|
||||
|
|
|
@ -54,22 +54,10 @@ void detect_board_type(void) {
|
|||
|
||||
// ///// Configuration detection ///// //
|
||||
bool has_external_debug_serial = 0;
|
||||
bool is_entering_bootmode = 0;
|
||||
|
||||
void detect_configuration(void) {
|
||||
// detect if external serial debugging is present
|
||||
has_external_debug_serial = detect_with_pull(GPIOA, 3, PULL_DOWN);
|
||||
|
||||
#ifdef PANDA
|
||||
if(hw_type == HW_TYPE_WHITE_PANDA) {
|
||||
// check if the ESP is trying to put me in boot mode
|
||||
is_entering_bootmode = !detect_with_pull(GPIOB, 0, PULL_UP);
|
||||
} else {
|
||||
is_entering_bootmode = 0;
|
||||
}
|
||||
#else
|
||||
is_entering_bootmode = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ///// Board functions ///// //
|
||||
|
|
|
@ -4,7 +4,7 @@ typedef void (*board_enable_can_transciever)(uint8_t transciever, bool enabled);
|
|||
typedef void (*board_enable_can_transcievers)(bool enabled);
|
||||
typedef void (*board_set_led)(uint8_t color, bool enabled);
|
||||
typedef void (*board_set_usb_power_mode)(uint8_t mode);
|
||||
typedef void (*board_set_esp_gps_mode)(uint8_t mode);
|
||||
typedef void (*board_set_gps_mode)(uint8_t mode);
|
||||
typedef void (*board_set_can_mode)(uint8_t mode);
|
||||
typedef void (*board_usb_power_mode_tick)(uint32_t uptime);
|
||||
typedef bool (*board_check_ignition)(void);
|
||||
|
@ -23,7 +23,7 @@ struct board {
|
|||
board_enable_can_transcievers enable_can_transcievers;
|
||||
board_set_led set_led;
|
||||
board_set_usb_power_mode set_usb_power_mode;
|
||||
board_set_esp_gps_mode set_esp_gps_mode;
|
||||
board_set_gps_mode set_gps_mode;
|
||||
board_set_can_mode set_can_mode;
|
||||
board_usb_power_mode_tick usb_power_mode_tick;
|
||||
board_check_ignition check_ignition;
|
||||
|
@ -56,10 +56,10 @@ struct board {
|
|||
#define USB_POWER_CDP 2U
|
||||
#define USB_POWER_DCP 3U
|
||||
|
||||
// ESP modes
|
||||
#define ESP_GPS_DISABLED 0U
|
||||
#define ESP_GPS_ENABLED 1U
|
||||
#define ESP_GPS_BOOTMODE 2U
|
||||
// GPS modes
|
||||
#define GPS_DISABLED 0U
|
||||
#define GPS_ENABLED 1U
|
||||
#define GPS_BOOTMODE 2U
|
||||
|
||||
// CAN modes
|
||||
#define CAN_MODE_NORMAL 0U
|
||||
|
|
|
@ -77,24 +77,24 @@ void black_set_usb_power_mode(uint8_t mode) {
|
|||
}
|
||||
}
|
||||
|
||||
void black_set_esp_gps_mode(uint8_t mode) {
|
||||
void black_set_gps_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case ESP_GPS_DISABLED:
|
||||
case GPS_DISABLED:
|
||||
// GPS OFF
|
||||
set_gpio_output(GPIOC, 14, 0);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
case ESP_GPS_ENABLED:
|
||||
case GPS_ENABLED:
|
||||
// GPS ON
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
break;
|
||||
case ESP_GPS_BOOTMODE:
|
||||
case GPS_BOOTMODE:
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
default:
|
||||
puts("Invalid ESP/GPS mode\n");
|
||||
puts("Invalid GPS mode\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ void black_init(void) {
|
|||
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
||||
|
||||
// Set default state of GPS
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
|
||||
// C10: OBD_SBU1_RELAY (harness relay driving output)
|
||||
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
||||
|
@ -240,7 +240,7 @@ const board board_black = {
|
|||
.enable_can_transcievers = black_enable_can_transcievers,
|
||||
.set_led = black_set_led,
|
||||
.set_usb_power_mode = black_set_usb_power_mode,
|
||||
.set_esp_gps_mode = black_set_esp_gps_mode,
|
||||
.set_gps_mode = black_set_gps_mode,
|
||||
.set_can_mode = black_set_can_mode,
|
||||
.usb_power_mode_tick = black_usb_power_mode_tick,
|
||||
.check_ignition = black_check_ignition,
|
||||
|
|
|
@ -23,7 +23,7 @@ void common_init_gpio(void){
|
|||
set_gpio_alternate(GPIOA, 12, GPIO_AF10_OTG_FS);
|
||||
GPIOA->OSPEEDR = GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12;
|
||||
|
||||
// A9,A10: USART 1 for talking to the ESP / GPS
|
||||
// A9,A10: USART 1 for talking to the GPS
|
||||
set_gpio_alternate(GPIOA, 9, GPIO_AF7_USART1);
|
||||
set_gpio_alternate(GPIOA, 10, GPIO_AF7_USART1);
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ void dos_set_usb_power_mode(uint8_t mode) {
|
|||
dos_set_bootkick(mode == USB_POWER_CDP);
|
||||
}
|
||||
|
||||
void dos_set_esp_gps_mode(uint8_t mode) {
|
||||
void dos_set_gps_mode(uint8_t mode) {
|
||||
UNUSED(mode);
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ const board board_dos = {
|
|||
.enable_can_transcievers = dos_enable_can_transcievers,
|
||||
.set_led = dos_set_led,
|
||||
.set_usb_power_mode = dos_set_usb_power_mode,
|
||||
.set_esp_gps_mode = dos_set_esp_gps_mode,
|
||||
.set_gps_mode = dos_set_gps_mode,
|
||||
.set_can_mode = dos_set_can_mode,
|
||||
.usb_power_mode_tick = dos_usb_power_mode_tick,
|
||||
.check_ignition = dos_check_ignition,
|
||||
|
|
|
@ -8,22 +8,22 @@ void grey_init(void) {
|
|||
white_grey_common_init();
|
||||
|
||||
// Set default state of GPS
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
}
|
||||
|
||||
void grey_set_esp_gps_mode(uint8_t mode) {
|
||||
void grey_set_gps_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case ESP_GPS_DISABLED:
|
||||
case GPS_DISABLED:
|
||||
// GPS OFF
|
||||
set_gpio_output(GPIOC, 14, 0);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
case ESP_GPS_ENABLED:
|
||||
case GPS_ENABLED:
|
||||
// GPS ON
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
break;
|
||||
case ESP_GPS_BOOTMODE:
|
||||
case GPS_BOOTMODE:
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
|
@ -41,7 +41,7 @@ const board board_grey = {
|
|||
.enable_can_transcievers = white_enable_can_transcievers,
|
||||
.set_led = white_set_led,
|
||||
.set_usb_power_mode = white_set_usb_power_mode,
|
||||
.set_esp_gps_mode = grey_set_esp_gps_mode,
|
||||
.set_gps_mode = grey_set_gps_mode,
|
||||
.set_can_mode = white_set_can_mode,
|
||||
.usb_power_mode_tick = white_usb_power_mode_tick,
|
||||
.check_ignition = white_check_ignition,
|
||||
|
|
|
@ -35,7 +35,7 @@ void pedal_set_usb_power_mode(uint8_t mode){
|
|||
puts("Trying to set USB power mode on pedal. This is not supported.\n");
|
||||
}
|
||||
|
||||
void pedal_set_esp_gps_mode(uint8_t mode) {
|
||||
void pedal_set_gps_mode(uint8_t mode) {
|
||||
UNUSED(mode);
|
||||
puts("Trying to set ESP/GPS mode on pedal. This is not supported.\n");
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ const board board_pedal = {
|
|||
.enable_can_transcievers = pedal_enable_can_transcievers,
|
||||
.set_led = pedal_set_led,
|
||||
.set_usb_power_mode = pedal_set_usb_power_mode,
|
||||
.set_esp_gps_mode = pedal_set_esp_gps_mode,
|
||||
.set_gps_mode = pedal_set_gps_mode,
|
||||
.set_can_mode = pedal_set_can_mode,
|
||||
.usb_power_mode_tick = pedal_usb_power_mode_tick,
|
||||
.check_ignition = pedal_check_ignition,
|
||||
|
|
|
@ -89,21 +89,21 @@ void uno_set_usb_power_mode(uint8_t mode) {
|
|||
}
|
||||
}
|
||||
|
||||
void uno_set_esp_gps_mode(uint8_t mode) {
|
||||
void uno_set_gps_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case ESP_GPS_DISABLED:
|
||||
case GPS_DISABLED:
|
||||
// GPS OFF
|
||||
set_gpio_output(GPIOB, 1, 0);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
uno_set_gps_load_switch(false);
|
||||
break;
|
||||
case ESP_GPS_ENABLED:
|
||||
case GPS_ENABLED:
|
||||
// GPS ON
|
||||
set_gpio_output(GPIOB, 1, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
uno_set_gps_load_switch(true);
|
||||
break;
|
||||
case ESP_GPS_BOOTMODE:
|
||||
case GPS_BOOTMODE:
|
||||
set_gpio_output(GPIOB, 1, 1);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
uno_set_gps_load_switch(true);
|
||||
|
@ -196,7 +196,7 @@ void uno_init(void) {
|
|||
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
||||
|
||||
// Set default state of GPS
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
|
||||
// C10: OBD_SBU1_RELAY (harness relay driving output)
|
||||
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
||||
|
@ -283,7 +283,7 @@ const board board_uno = {
|
|||
.enable_can_transcievers = uno_enable_can_transcievers,
|
||||
.set_led = uno_set_led,
|
||||
.set_usb_power_mode = uno_set_usb_power_mode,
|
||||
.set_esp_gps_mode = uno_set_esp_gps_mode,
|
||||
.set_gps_mode = uno_set_gps_mode,
|
||||
.set_can_mode = uno_set_can_mode,
|
||||
.usb_power_mode_tick = uno_usb_power_mode_tick,
|
||||
.check_ignition = uno_check_ignition,
|
||||
|
|
|
@ -71,21 +71,21 @@ void white_set_usb_power_mode(uint8_t mode){
|
|||
}
|
||||
}
|
||||
|
||||
void white_set_esp_gps_mode(uint8_t mode) {
|
||||
void white_set_gps_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case ESP_GPS_DISABLED:
|
||||
case GPS_DISABLED:
|
||||
// ESP OFF
|
||||
set_gpio_output(GPIOC, 14, 0);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
#ifndef EON
|
||||
case ESP_GPS_ENABLED:
|
||||
case GPS_ENABLED:
|
||||
// ESP ON
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
break;
|
||||
#endif
|
||||
case ESP_GPS_BOOTMODE:
|
||||
case GPS_BOOTMODE:
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
|
@ -324,12 +324,8 @@ void white_grey_common_init(void) {
|
|||
void white_init(void) {
|
||||
white_grey_common_init();
|
||||
|
||||
// Set default state of ESP
|
||||
#ifdef EON
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
#else
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
#endif
|
||||
// Set ESP off by default
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
}
|
||||
|
||||
const harness_configuration white_harness_config = {
|
||||
|
@ -344,7 +340,7 @@ const board board_white = {
|
|||
.enable_can_transcievers = white_enable_can_transcievers,
|
||||
.set_led = white_set_led,
|
||||
.set_usb_power_mode = white_set_usb_power_mode,
|
||||
.set_esp_gps_mode = white_set_esp_gps_mode,
|
||||
.set_gps_mode = white_set_gps_mode,
|
||||
.set_can_mode = white_set_can_mode,
|
||||
.usb_power_mode_tick = white_usb_power_mode_tick,
|
||||
.check_ignition = white_check_ignition,
|
||||
|
|
|
@ -50,8 +50,8 @@ void debug_ring_callback(uart_ring *ring);
|
|||
|
||||
// ******************************** UART buffers ********************************
|
||||
|
||||
// esp_gps = USART1
|
||||
UART_BUFFER(esp_gps, FIFO_SIZE_DMA, FIFO_SIZE_INT, USART1, NULL, true)
|
||||
// gps = USART1
|
||||
UART_BUFFER(gps, FIFO_SIZE_DMA, FIFO_SIZE_INT, USART1, NULL, true)
|
||||
|
||||
// lin1, K-LINE = UART5
|
||||
// lin2, L-LINE = USART3
|
||||
|
@ -68,7 +68,7 @@ uart_ring *get_ring_by_number(int a) {
|
|||
ring = &uart_ring_debug;
|
||||
break;
|
||||
case 1:
|
||||
ring = &uart_ring_esp_gps;
|
||||
ring = &uart_ring_gps;
|
||||
break;
|
||||
case 2:
|
||||
ring = &uart_ring_lin1;
|
||||
|
@ -185,8 +185,8 @@ void uart_interrupt_handler(uart_ring *q) {
|
|||
// Reset IDLE flag
|
||||
UART_READ_DR(q->uart)
|
||||
|
||||
if(q == &uart_ring_esp_gps){
|
||||
dma_pointer_handler(&uart_ring_esp_gps, DMA2_Stream5->NDTR);
|
||||
if(q == &uart_ring_gps){
|
||||
dma_pointer_handler(&uart_ring_gps, DMA2_Stream5->NDTR);
|
||||
} else {
|
||||
#ifdef DEBUG_UART
|
||||
puts("No IDLE dma_pointer_handler implemented for this UART.");
|
||||
|
@ -197,7 +197,7 @@ void uart_interrupt_handler(uart_ring *q) {
|
|||
EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
void USART1_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_esp_gps); }
|
||||
void USART1_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_gps); }
|
||||
void USART2_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_debug); }
|
||||
void USART3_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin2); }
|
||||
void UART5_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin1); }
|
||||
|
@ -219,7 +219,7 @@ void DMA2_Stream5_IRQ_Handler(void) {
|
|||
}
|
||||
|
||||
// Re-calculate write pointer and reset flags
|
||||
dma_pointer_handler(&uart_ring_esp_gps, DMA2_Stream5->NDTR);
|
||||
dma_pointer_handler(&uart_ring_gps, DMA2_Stream5->NDTR);
|
||||
DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5;
|
||||
|
||||
EXIT_CRITICAL();
|
||||
|
@ -229,7 +229,7 @@ void DMA2_Stream5_IRQ_Handler(void) {
|
|||
|
||||
void dma_rx_init(uart_ring *q) {
|
||||
// Initialization is UART-dependent
|
||||
if(q == &uart_ring_esp_gps){
|
||||
if(q == &uart_ring_gps){
|
||||
// DMA2, stream 5, channel 4
|
||||
|
||||
// Disable FIFO mode (enable direct)
|
||||
|
|
|
@ -64,13 +64,9 @@ void early(void) {
|
|||
|
||||
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
|
||||
#ifdef PANDA
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
#endif
|
||||
current_board->set_led(LED_GREEN, 1);
|
||||
jump_to_bootloader();
|
||||
}
|
||||
|
||||
if (is_entering_bootmode) {
|
||||
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
|
||||
}
|
||||
}
|
21
board/main.c
21
board/main.c
|
@ -400,24 +400,24 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
|
|||
// **** 0xd9: set ESP power
|
||||
case 0xd9:
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
} else if (setup->b.wValue.w == 2U) {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_BOOTMODE);
|
||||
current_board->set_gps_mode(GPS_BOOTMODE);
|
||||
} else {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
}
|
||||
break;
|
||||
// **** 0xda: reset ESP, with optional boot mode
|
||||
case 0xda:
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
delay(1000000);
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_BOOTMODE);
|
||||
current_board->set_gps_mode(GPS_BOOTMODE);
|
||||
} else {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
}
|
||||
delay(1000000);
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
break;
|
||||
// **** 0xdb: set GMLAN (white/grey) or OBD CAN (black) multiplexing mode
|
||||
case 0xdb:
|
||||
|
@ -493,7 +493,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
|
|||
}
|
||||
|
||||
// TODO: Remove this again and fix boardd code to hande the message bursts instead of single chars
|
||||
if (ur == &uart_ring_esp_gps) {
|
||||
if (ur == &uart_ring_gps) {
|
||||
dma_pointer_handler(ur, DMA2_Stream5->NDTR);
|
||||
}
|
||||
|
||||
|
@ -796,7 +796,6 @@ int main(void) {
|
|||
puts("Config:\n");
|
||||
puts(" Board type: "); puts(current_board->board_type); puts("\n");
|
||||
puts(has_external_debug_serial ? " Real serial\n" : " USB serial\n");
|
||||
puts(is_entering_bootmode ? " ESP wants bootmode\n" : " No bootmode\n");
|
||||
|
||||
// init board
|
||||
current_board->init();
|
||||
|
@ -812,10 +811,10 @@ int main(void) {
|
|||
}
|
||||
|
||||
if (board_has_gps()) {
|
||||
uart_init(&uart_ring_esp_gps, 9600);
|
||||
uart_init(&uart_ring_gps, 9600);
|
||||
} else {
|
||||
// enable ESP uart
|
||||
uart_init(&uart_ring_esp_gps, 115200);
|
||||
uart_init(&uart_ring_gps, 115200);
|
||||
}
|
||||
|
||||
if(board_has_lin()){
|
||||
|
|
|
@ -32,9 +32,9 @@ void set_power_save_state(int state) {
|
|||
|
||||
// Switch EPS/GPS
|
||||
if (enable) {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
} else {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
}
|
||||
|
||||
if(board_has_gmlan()){
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
proxy
|
||||
*.bin
|
||||
esp-open-sdk
|
||||
a.out
|
||||
cert.h
|
||||
gitversion.h
|
||||
esp-open-sdk.dmg
|
||||
obj/*
|
|
@ -1,101 +0,0 @@
|
|||
ELM327 support for panda
|
||||
======
|
||||
The panda now has basic ELM327 support.
|
||||
|
||||
### What is ELM327?
|
||||
|
||||
ELM327 is a command protocol for interfacing with cars using an OBD-II
|
||||
port to read [list](standard vehicle diagnostic codes). ELM327
|
||||
originally referred to a line of programmable microcontrollers that
|
||||
implemented the ELM327 command protocol, and are still being
|
||||
developed.
|
||||
|
||||
ELM327 devices present a shell and commands are sent via a UART. The
|
||||
official ELM327 chips only support raw UART communication, but most
|
||||
devices built with the ELM327 devices (official or clones) expose the
|
||||
UART in a more modern way (Wifi, USB, etc).
|
||||
|
||||
Mechanics use ELM to diagnose vehicles, and reset fault codes in the
|
||||
car's computer after fixing the issue (turning off the dreaded check
|
||||
engine light). Car owners can use ELM devices to perform the same
|
||||
diagnostics in their garage using either a raw terminal to send
|
||||
commands to the ELM device directly, or using a GUI (like one of
|
||||
several popular smart phone apps) to translate the OBD error codes
|
||||
into readable messages. These GUIs also often allow monitoring of the
|
||||
performance of the car's speed, engine rpm, etc.
|
||||
|
||||
The panda natively supports sending all the important OBD diagnostic
|
||||
messages, but ELM327 support removes the need for the user to manually
|
||||
craft CAN or LIN packets using the native panda API, and grants
|
||||
compatibility with many existing tools.
|
||||
|
||||
[Wikipedia](https://en.wikipedia.org/wiki/ELM327) can provide
|
||||
additional information.
|
||||
|
||||
### OBD Protocols?
|
||||
|
||||
While the commands that the OBD standard describe are in fact
|
||||
standard, there are several different protocols that those messages
|
||||
can be sent and received with. All cars after 1991 support one of
|
||||
these protocols. Which one depends on the car's year and country, as
|
||||
legal requirements change over the years.
|
||||
|
||||
The panda supports the most popular/modern of these protocols, and all
|
||||
but two can be added as needed. Below is a chart of the OBD-II
|
||||
protocols supported by the panda.
|
||||
|
||||
| Protocol | Support Status |
|
||||
| --- | --- |
|
||||
| SAE J1850 PWM (41.6 kbit/s) | Never/Obsolete |
|
||||
| SAE J1850 VPW (10.4 kbit/s) | Never/Obsolete |
|
||||
| ISO 9141-2 (5 baud init, 10.4 kbit/s) | Unsupported |
|
||||
| ISO 14230-4 KWP (5 baud init, 10.4 kbit/s) | Unsupported |
|
||||
| ISO 14230-4 KWP (fast init, 10.4 kbit/s) | Supported |
|
||||
| ISO 15765-4 CAN (11 bit ID, 500 kbit/s) | Supported |
|
||||
| ISO 15765-4 CAN (29 bit ID, 500 kbit/s) | Supported |
|
||||
| ISO 15765-4 CAN (11 bit ID, 250 kbit/s) | Supported |
|
||||
| ISO 15765-4 CAN (29 bit ID, 250 kbit/s) | Supported |
|
||||
| SAE J1939 (250kbps) | Unsupported |
|
||||
|
||||
### The Implementation
|
||||
|
||||
The panda ELM327 implementation is not a full implementation of all
|
||||
the features of the official ELM327 microcontroller. Like most ELM327
|
||||
clones, the panda reports its ELM version as the unreleased version
|
||||
1.5, despite only implementing commands from protocol version 1.0.
|
||||
|
||||
|
||||
### Testing
|
||||
|
||||
These tests require two pandas. One to be tested, and the second to
|
||||
simulate the vehicle.
|
||||
|
||||
The panda used to simulate the vehicle must be plugged into a USB port
|
||||
of the testing computer.
|
||||
|
||||
The computer running the tests must be connected to the panda being
|
||||
tested's wifi network.
|
||||
|
||||
The following command will run the tests (nosetest should work fine
|
||||
instead of pytest if you still prefer using that). The CANSIMSERIAL
|
||||
environment variable will force the car simulator to use the correct
|
||||
panda as the simulator if multiple pandas are attached via usb to the
|
||||
host computer.
|
||||
|
||||
```
|
||||
CANSIMSERIAL=car_sim_panda_serial pytest tests/automated/elm_wifi.py
|
||||
```
|
||||
|
||||
A single test can be run by putting the test name after the file name
|
||||
and two colons, like so:
|
||||
|
||||
```
|
||||
CANSIMSERIAL=car_sim_panda_serial pytest tests/automated/elm_wifi.py::test_important_thing
|
||||
```
|
||||
|
||||
For more detail, provide the -s (show output) and the -vv (very
|
||||
verbose) flags.
|
||||
|
||||
```
|
||||
CANSIMSERIAL=car_sim_panda_serial pytest -s -vv tests/automated/elm_wifi.py
|
||||
```
|
|
@ -1,74 +0,0 @@
|
|||
PATH := esp-open-sdk/xtensa-lx106-elf/bin:$(PATH)
|
||||
CC = esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc
|
||||
CFLAGS = -Iinclude/ -I. -I../ -mlongcalls -Iesp-open-sdk/ESP8266_NONOS_SDK_V1.5.4_16_05_20/driver_lib/include -std=c99 -DICACHE_FLASH
|
||||
LDLIBS = -nostdlib -Wl,--start-group -lmain -lnet80211 -lwpa -llwip -lpp -lphy -Wl,--end-group -lgcc -ldriver -Wl,--gc-sections
|
||||
LDFLAGS = -Teagle.app.v6.ld
|
||||
OBJCP = esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-objcopy
|
||||
SDK_BASE = esp-open-sdk/ESP8266_NONOS_SDK_V1.5.4_16_05_20
|
||||
|
||||
ifeq ($(RELEASE),1)
|
||||
CERT = ../../pandaextra/certs/releaseesp
|
||||
else
|
||||
CERT = ../certs/debugesp
|
||||
CFLAGS += "-DALLOW_DEBUG"
|
||||
endif
|
||||
|
||||
flashall: user1.bin user2.bin
|
||||
../python/esptool.py write_flash 0 $(SDK_BASE)/bin/boot_v1.5.bin 0x01000 user1.bin 0x81000 user2.bin 0x3FE000 $(SDK_BASE)/bin/blank.bin
|
||||
|
||||
proxy-0x00000.bin: proxy
|
||||
../python/esptool.py elf2image $^
|
||||
|
||||
proxy: proxy.o elm327.o webserver.o sha.o
|
||||
|
||||
obj/proxy.o: proxy.c
|
||||
$(CC) $(CFLAGS) -c $^ -o $@
|
||||
|
||||
obj/elm327.o: elm327.c
|
||||
$(CC) $(CFLAGS) -c $^ -o $@
|
||||
|
||||
obj/webserver.o: webserver.c obj/cert.h obj/gitversion.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
obj/cert.h: ../crypto/getcertheader.py
|
||||
../crypto/getcertheader.py ../certs/debugesp.pub ../certs/releaseesp.pub > obj/cert.h
|
||||
|
||||
include ../common/version.mk
|
||||
|
||||
obj/sha.o: ../crypto/sha.c
|
||||
$(CC) $(CFLAGS) -c $^ -o $@
|
||||
|
||||
obj/rsa.o: ../crypto/rsa.c
|
||||
$(CC) $(CFLAGS) -c $^ -o $@
|
||||
|
||||
oldflash: proxy-0x00000.bin
|
||||
../python/esptool.py write_flash 0 proxy-0x00000.bin 0x40000 proxy-0x40000.bin
|
||||
|
||||
user1.bin: obj/proxy.o obj/elm327.o obj/webserver.o obj/sha.o obj/rsa.o
|
||||
$(CC) $(CFLAGS) $^ -o a.out -L$(SDK_BASE)/ld -T$(SDK_BASE)/ld/eagle.app.v6.new.1024.app1.ld $(LDLIBS)
|
||||
$(OBJCP) --only-section .text -O binary a.out eagle.app.v6.text.bin
|
||||
$(OBJCP) --only-section .data -O binary a.out eagle.app.v6.data.bin
|
||||
$(OBJCP) --only-section .rodata -O binary a.out eagle.app.v6.rodata.bin
|
||||
$(OBJCP) --only-section .irom0.text -O binary a.out eagle.app.v6.irom0text.bin
|
||||
COMPILE=gcc python2 ./esp-open-sdk/ESP8266_NONOS_SDK_V1.5.4_16_05_20/tools/gen_appbin.py a.out 2 0 32 4 0
|
||||
rm -f eagle.app.v6.*.bin
|
||||
mv eagle.app.flash.bin $@
|
||||
../crypto/sign.py $@ $@ $(CERT)
|
||||
|
||||
user2.bin: obj/proxy.o obj/elm327.o obj/webserver.o obj/sha.o obj/rsa.o
|
||||
$(CC) $(CFLAGS) $^ -o a.out -L$(SDK_BASE)/ld -T$(SDK_BASE)/ld/eagle.app.v6.new.1024.app2.ld $(LDLIBS)
|
||||
$(OBJCP) --only-section .text -O binary a.out eagle.app.v6.text.bin
|
||||
$(OBJCP) --only-section .data -O binary a.out eagle.app.v6.data.bin
|
||||
$(OBJCP) --only-section .rodata -O binary a.out eagle.app.v6.rodata.bin
|
||||
$(OBJCP) --only-section .irom0.text -O binary a.out eagle.app.v6.irom0text.bin
|
||||
COMPILE=gcc python2 ./esp-open-sdk/ESP8266_NONOS_SDK_V1.5.4_16_05_20/tools/gen_appbin.py a.out 2 0 32 4 0
|
||||
rm -f eagle.app.v6.*.bin
|
||||
mv eagle.app.flash.bin $@
|
||||
../crypto/sign.py $@ $@ $(CERT)
|
||||
|
||||
ota: user1.bin user2.bin
|
||||
curl http://192.168.0.10/espupdate1 --upload-file user1.bin
|
||||
curl http://192.168.0.10/espupdate2 --upload-file user2.bin
|
||||
|
||||
clean:
|
||||
rm -f proxy proxy.o proxy-0x00000.bin proxy-0x40000.bin eagle.app.* user1.bin user2.bin a.out obj/*
|
|
@ -1,22 +0,0 @@
|
|||
|
||||
Dependencies
|
||||
-----
|
||||
|
||||
**Debian / Ubuntu**
|
||||
|
||||
```
|
||||
./get_sdk.sh
|
||||
```
|
||||
|
||||
**Mac**
|
||||
|
||||
```
|
||||
./get_sdk_mac.sh
|
||||
```
|
||||
|
||||
Programming
|
||||
-----
|
||||
|
||||
```
|
||||
make
|
||||
```
|
1578
boardesp/elm327.c
1578
boardesp/elm327.c
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
sudo apt-get install make unrar-free autoconf automake libtool gcc g++ gperf \
|
||||
flex bison texinfo gawk ncurses-dev libexpat-dev python-dev python python-serial \
|
||||
sed git unzip bash help2man wget bzip2
|
||||
# huh?
|
||||
sudo apt-get install libtool
|
||||
sudo apt-get install libtool-bin
|
||||
git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
|
||||
cd esp-open-sdk
|
||||
git checkout 03f5e898a059451ec5f3de30e7feff30455f7cec
|
||||
cp ../python2_make.py .
|
||||
python2 python2_make.py 'LD_LIBRARY_PATH="" make STANDALONE=y'
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
|
||||
cd esp-open-sdk
|
||||
git checkout 03f5e898a059451ec5f3de30e7feff30455f7cec
|
||||
cp ../python2_make.py .
|
||||
python2 python2_make.py 'LD_LIBRARY_PATH="" make STANDALONE=y'
|
|
@ -1,32 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# from http://www.esp8266.com/wiki/doku.php?id=setup-osx-compiler-esp8266
|
||||
|
||||
brew install gnu-sed --with-default-names
|
||||
brew tap homebrew/dupes
|
||||
brew install gperf
|
||||
brew install grep
|
||||
brew install autoconf
|
||||
brew install binutils
|
||||
brew install gawk
|
||||
brew install wget
|
||||
brew install automake
|
||||
brew install libtool
|
||||
brew install help2man
|
||||
|
||||
brew uninstall gperf
|
||||
|
||||
hdiutil create esp-open-sdk.dmg -volname "esp-open-sdk" -size 10g -fs "Case-sensitive HFS+"
|
||||
hdiutil mount esp-open-sdk.dmg
|
||||
ln -s /Volumes/esp-open-sdk esp-open-sdk
|
||||
cd esp-open-sdk
|
||||
|
||||
git init
|
||||
git remote add origin https://github.com/pfalcon/esp-open-sdk.git
|
||||
git fetch origin
|
||||
git checkout 03f5e898a059451ec5f3de30e7feff30455f7cec
|
||||
git submodule init
|
||||
git submodule update --recursive
|
||||
|
||||
cp ../python2_make.py .
|
||||
python2 python2_make.py 'make STANDALONE=y'
|
|
@ -1,78 +0,0 @@
|
|||
#ifndef ESPMISSINGINCLUDES_H
|
||||
#define ESPMISSINGINCLUDES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <c_types.h>
|
||||
#include <os_type.h>
|
||||
|
||||
|
||||
int strcasecmp(const char *a, const char *b);
|
||||
#ifndef FREERTOS
|
||||
#include <eagle_soc.h>
|
||||
#include <ets_sys.h>
|
||||
//Missing function prototypes in include folders. Gcc will warn on these if we don't define 'em anywhere.
|
||||
//MOST OF THESE ARE GUESSED! but they seem to swork and shut up the compiler.
|
||||
typedef struct espconn espconn;
|
||||
|
||||
int atoi(const char *nptr);
|
||||
void ets_install_putc1(void *routine);
|
||||
void ets_isr_attach(int intr, void *handler, void *arg);
|
||||
void ets_isr_mask(unsigned intr);
|
||||
void ets_isr_unmask(unsigned intr);
|
||||
int ets_memcmp(const void *s1, const void *s2, size_t n);
|
||||
void *ets_memcpy(void *dest, const void *src, size_t n);
|
||||
void *ets_memset(void *s, int c, size_t n);
|
||||
int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
int ets_str2macaddr(void *, void *);
|
||||
int ets_strcmp(const char *s1, const char *s2);
|
||||
char *ets_strcpy(char *dest, const char *src);
|
||||
size_t ets_strlen(const char *s);
|
||||
int ets_strncmp(const char *s1, const char *s2, int len);
|
||||
char *ets_strncpy(char *dest, const char *src, size_t n);
|
||||
char *ets_strstr(const char *haystack, const char *needle);
|
||||
void ets_timer_arm_new(os_timer_t *a, int b, int c, int isMstimer);
|
||||
void ets_timer_disarm(os_timer_t *a);
|
||||
void ets_timer_setfn(os_timer_t *t, ETSTimerFunc *fn, void *parg);
|
||||
void ets_update_cpu_frequency(int freqmhz);
|
||||
void *os_memmove(void *dest, const void *src, size_t n);
|
||||
int os_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
int os_printf_plus(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void uart_div_modify(int no, unsigned int freq);
|
||||
uint8 wifi_get_opmode(void);
|
||||
uint32 system_get_time();
|
||||
int rand(void);
|
||||
void ets_bzero(void *s, size_t n);
|
||||
void ets_delay_us(int ms);
|
||||
|
||||
//Hack: this is defined in SDK 1.4.0 and undefined in 1.3.0. It's only used for this, the symbol itself
|
||||
//has no meaning here.
|
||||
#ifndef RC_LIMIT_P2P_11N
|
||||
//Defs for SDK <1.4.0
|
||||
void *pvPortMalloc(size_t xWantedSize);
|
||||
void *pvPortZalloc(size_t);
|
||||
void vPortFree(void *ptr);
|
||||
void *vPortMalloc(size_t xWantedSize);
|
||||
void pvPortFree(void *ptr);
|
||||
#else
|
||||
void *pvPortMalloc(size_t xWantedSize, const char *file, int line);
|
||||
void *pvPortZalloc(size_t, const char *file, int line);
|
||||
void vPortFree(void *ptr, const char *file, int line);
|
||||
void *vPortMalloc(size_t xWantedSize, const char *file, int line);
|
||||
void pvPortFree(void *ptr, const char *file, int line);
|
||||
#endif
|
||||
|
||||
//Standard PIN_FUNC_SELECT gives a warning. Replace by a non-warning one.
|
||||
#ifdef PIN_FUNC_SELECT
|
||||
#undef PIN_FUNC_SELECT
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) do { \
|
||||
WRITE_PERI_REG(PIN_NAME, \
|
||||
(READ_PERI_REG(PIN_NAME) \
|
||||
& (~(PERIPHS_IO_MUX_FUNC<<PERIPHS_IO_MUX_FUNC_S))) \
|
||||
|( (((FUNC&BIT2)<<2)|(FUNC&0x3))<<PERIPHS_IO_MUX_FUNC_S) ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
373
boardesp/proxy.c
373
boardesp/proxy.c
|
@ -1,373 +0,0 @@
|
|||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "gpio.h"
|
||||
#include "os_type.h"
|
||||
#include "user_interface.h"
|
||||
#include "espconn.h"
|
||||
|
||||
#include "driver/spi_interface.h"
|
||||
#include "driver/uart.h"
|
||||
#include "crypto/sha.h"
|
||||
|
||||
#define MIN(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
#define MAX(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
char ssid[32];
|
||||
char password[] = "testing123";
|
||||
int wifi_secure_mode = 0;
|
||||
|
||||
static const int pin = 2;
|
||||
|
||||
// Structure holding the TCP connection information.
|
||||
struct espconn tcp_conn;
|
||||
// TCP specific protocol structure.
|
||||
esp_tcp tcp_proto;
|
||||
|
||||
// interrupt communication on port 1338, UDP!
|
||||
struct espconn inter_conn;
|
||||
esp_udp inter_proto;
|
||||
|
||||
uint32_t sendData[0x14] = {0};
|
||||
uint32_t recvData[0x40] = {0};
|
||||
|
||||
static int ICACHE_FLASH_ATTR __spi_comm(char *dat, int len, uint32_t *recvData, int recvDataLen) {
|
||||
unsigned int length = 0;
|
||||
|
||||
SpiData spiData;
|
||||
|
||||
spiData.cmd = 2;
|
||||
spiData.cmdLen = 0;
|
||||
spiData.addr = NULL;
|
||||
spiData.addrLen = 0;
|
||||
|
||||
// float boot pin
|
||||
gpio_output_set(0, 0, 0, (1 << 4));
|
||||
|
||||
// manual CS pin
|
||||
gpio_output_set(0, (1 << 5), 0, 0);
|
||||
memset(sendData, 0xCC, 0x14);
|
||||
|
||||
// wait for ST to respond to CS interrupt
|
||||
os_delay_us(50);
|
||||
|
||||
// send request
|
||||
memcpy(((void*)sendData), dat, len);
|
||||
spiData.data = sendData;
|
||||
spiData.dataLen = 0x14;
|
||||
SPIMasterSendData(SpiNum_HSPI, &spiData);
|
||||
|
||||
#define SPI_TIMEOUT 50000
|
||||
// give the ST time to be ready, up to 500ms
|
||||
int i;
|
||||
for (i = 0; (gpio_input_get() & (1 << 4)) && i < SPI_TIMEOUT; i++) {
|
||||
os_delay_us(10);
|
||||
system_soft_wdt_feed();
|
||||
}
|
||||
|
||||
// TODO: handle this better
|
||||
if (i == SPI_TIMEOUT) {
|
||||
os_printf("ERROR: SPI receive failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// blank out recvData
|
||||
memset(recvData, 0x00, 0x44);
|
||||
|
||||
// receive the length
|
||||
spiData.data = recvData;
|
||||
spiData.dataLen = 4;
|
||||
if(SPIMasterRecvData(SpiNum_HSPI, &spiData) == -1) {
|
||||
// TODO: Handle gracefully. Maybe fail if len read fails?
|
||||
os_printf("SPI: Failed to recv length\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
length = recvData[0];
|
||||
if (length > 0x40) {
|
||||
os_printf("SPI: BAD LENGTH RECEIVED %x\n", length);
|
||||
length = 0;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// got response, 0x40 works, 0x44 does not
|
||||
spiData.data = recvData+1;
|
||||
spiData.dataLen = (length+3)&(~3); // recvDataLen;
|
||||
if(SPIMasterRecvData(SpiNum_HSPI, &spiData) == -1) {
|
||||
// TODO: Handle gracefully. Maybe retry if payload failed.
|
||||
os_printf("SPI: Failed to recv payload\n");
|
||||
length = 0;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
// clear CS
|
||||
gpio_output_set((1 << 5), 0, 0, 0);
|
||||
|
||||
// set boot pin back
|
||||
gpio_output_set((1 << 4), 0, (1 << 4), 0);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int ICACHE_FLASH_ATTR spi_comm(char *dat, int len, uint32_t *recvData, int recvDataLen) {
|
||||
// blink the led during SPI comm
|
||||
if (GPIO_REG_READ(GPIO_OUT_ADDRESS) & (1 << pin)) {
|
||||
// set gpio low
|
||||
gpio_output_set(0, (1 << pin), 0, 0);
|
||||
} else {
|
||||
// set gpio high
|
||||
gpio_output_set((1 << pin), 0, 0, 0);
|
||||
}
|
||||
|
||||
return __spi_comm(dat, len, recvData, recvDataLen);
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR tcp_rx_cb(void *arg, char *data, uint16_t len) {
|
||||
// nothing too big
|
||||
if (len > 0x14) return;
|
||||
|
||||
// do the SPI comm
|
||||
spi_comm(data, len, recvData, 0x40);
|
||||
|
||||
espconn_send(&tcp_conn, recvData, 0x44);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR tcp_connect_cb(void *arg) {
|
||||
struct espconn *conn = (struct espconn *)arg;
|
||||
espconn_set_opt(&tcp_conn, ESPCONN_NODELAY);
|
||||
espconn_regist_recvcb(conn, tcp_rx_cb);
|
||||
}
|
||||
|
||||
// must be 0x44, because we can fit 4 more
|
||||
uint8_t buf[0x44*0x10];
|
||||
int queue_send_len = -1;
|
||||
|
||||
void ICACHE_FLASH_ATTR poll_can(void *arg) {
|
||||
uint8_t timerRecvData[0x44] = {0};
|
||||
int i = 0;
|
||||
int j;
|
||||
|
||||
while (i < 0x40) {
|
||||
int len = spi_comm("\x01\x00\x00\x00", 4, timerRecvData, 0x40);
|
||||
if (len == 0) break;
|
||||
if (len > 0x40) { os_printf("SPI LENGTH ERROR!"); break; }
|
||||
|
||||
// if it sends it, assume it's valid CAN
|
||||
for (j = 0; j < len; j += 0x10) {
|
||||
memcpy(buf + i*0x10, (timerRecvData+4)+j, 0x10);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != 0) {
|
||||
int ret = espconn_sendto(&inter_conn, buf, i*0x10);
|
||||
if (ret != 0) {
|
||||
os_printf("send failed: %d\n", ret);
|
||||
queue_send_len = i*0x10;
|
||||
} else {
|
||||
queue_send_len = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int udp_countdown = 0;
|
||||
|
||||
static volatile os_timer_t udp_callback;
|
||||
void ICACHE_FLASH_ATTR udp_callback_func(void *arg) {
|
||||
if (queue_send_len == -1) {
|
||||
poll_can(NULL);
|
||||
} else {
|
||||
int ret = espconn_sendto(&inter_conn, buf, queue_send_len);
|
||||
if (ret == 0) {
|
||||
queue_send_len = -1;
|
||||
}
|
||||
}
|
||||
if (udp_countdown > 0) {
|
||||
os_timer_arm(&udp_callback, 5, 0);
|
||||
udp_countdown--;
|
||||
} else {
|
||||
os_printf("UDP timeout\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR inter_recv_cb(void *arg, char *pusrdata, unsigned short length) {
|
||||
remot_info *premot = NULL;
|
||||
if (espconn_get_connection_info(&inter_conn,&premot,0) == ESPCONN_OK) {
|
||||
inter_conn.proto.udp->remote_port = premot->remote_port;
|
||||
inter_conn.proto.udp->remote_ip[0] = premot->remote_ip[0];
|
||||
inter_conn.proto.udp->remote_ip[1] = premot->remote_ip[1];
|
||||
inter_conn.proto.udp->remote_ip[2] = premot->remote_ip[2];
|
||||
inter_conn.proto.udp->remote_ip[3] = premot->remote_ip[3];
|
||||
|
||||
|
||||
if (udp_countdown == 0) {
|
||||
os_printf("UDP recv\n");
|
||||
udp_countdown = 200*5;
|
||||
|
||||
// start 5 second timer
|
||||
os_timer_disarm(&udp_callback);
|
||||
os_timer_setfn(&udp_callback, (os_timer_func_t *)udp_callback_func, NULL);
|
||||
os_timer_arm(&udp_callback, 5, 0);
|
||||
} else {
|
||||
udp_countdown = 200*5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR wifi_configure(int secure) {
|
||||
wifi_secure_mode = secure;
|
||||
|
||||
// start wifi AP
|
||||
wifi_set_opmode(SOFTAP_MODE);
|
||||
struct softap_config config = {0};
|
||||
wifi_softap_get_config(&config);
|
||||
strcpy(config.ssid, ssid);
|
||||
if (wifi_secure_mode == 0) strcat(config.ssid, "-pair");
|
||||
strcpy(config.password, password);
|
||||
config.ssid_len = strlen(config.ssid);
|
||||
config.authmode = wifi_secure_mode ? AUTH_WPA2_PSK : AUTH_OPEN;
|
||||
config.beacon_interval = 100;
|
||||
config.max_connection = 4;
|
||||
wifi_softap_set_config(&config);
|
||||
|
||||
if (wifi_secure_mode) {
|
||||
// setup tcp server
|
||||
tcp_proto.local_port = 1337;
|
||||
tcp_conn.type = ESPCONN_TCP;
|
||||
tcp_conn.state = ESPCONN_NONE;
|
||||
tcp_conn.proto.tcp = &tcp_proto;
|
||||
espconn_regist_connectcb(&tcp_conn, tcp_connect_cb);
|
||||
espconn_accept(&tcp_conn);
|
||||
espconn_regist_time(&tcp_conn, 60, 0); // 60s timeout for all connections
|
||||
|
||||
// setup inter server
|
||||
inter_proto.local_port = 1338;
|
||||
const char udp_remote_ip[4] = {255, 255, 255, 255};
|
||||
os_memcpy(inter_proto.remote_ip, udp_remote_ip, 4);
|
||||
inter_proto.remote_port = 1338;
|
||||
|
||||
inter_conn.type = ESPCONN_UDP;
|
||||
inter_conn.proto.udp = &inter_proto;
|
||||
|
||||
espconn_regist_recvcb(&inter_conn, inter_recv_cb);
|
||||
espconn_create(&inter_conn);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR wifi_init() {
|
||||
// default ssid and password
|
||||
memset(ssid, 0, 32);
|
||||
os_sprintf(ssid, "panda-%08x-BROKEN", system_get_chip_id());
|
||||
|
||||
// fetch secure ssid and password
|
||||
// update, try 20 times, for 1 second
|
||||
for (int i = 0; i < 20; i++) {
|
||||
uint8_t digest[SHA_DIGEST_SIZE];
|
||||
char resp[0x20];
|
||||
__spi_comm("\x00\x00\x00\x00\x40\xD0\x00\x00\x00\x00\x20\x00", 0xC, recvData, 0x40);
|
||||
memcpy(resp, recvData+1, 0x20);
|
||||
|
||||
SHA_hash(resp, 0x1C, digest);
|
||||
if (memcmp(digest, resp+0x1C, 4) == 0) {
|
||||
// OTP is valid
|
||||
memcpy(ssid+6, resp, 0x10);
|
||||
memcpy(password, resp+0x10, 10);
|
||||
break;
|
||||
}
|
||||
os_delay_us(50000);
|
||||
}
|
||||
os_printf("Finished getting SID\n");
|
||||
os_printf(ssid);
|
||||
os_printf("\n");
|
||||
|
||||
// set IP
|
||||
wifi_softap_dhcps_stop(); //stop DHCP before setting static IP
|
||||
struct ip_info ip_config;
|
||||
IP4_ADDR(&ip_config.ip, 192, 168, 0, 10);
|
||||
IP4_ADDR(&ip_config.gw, 0, 0, 0, 0);
|
||||
IP4_ADDR(&ip_config.netmask, 255, 255, 255, 0);
|
||||
wifi_set_ip_info(SOFTAP_IF, &ip_config);
|
||||
int stupid_gateway = 0;
|
||||
wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &stupid_gateway);
|
||||
wifi_softap_dhcps_start();
|
||||
|
||||
wifi_configure(0);
|
||||
}
|
||||
|
||||
#define LOOP_PRIO 2
|
||||
#define QUEUE_SIZE 1
|
||||
static os_event_t my_queue[QUEUE_SIZE];
|
||||
void loop();
|
||||
|
||||
void ICACHE_FLASH_ATTR web_init();
|
||||
void ICACHE_FLASH_ATTR elm327_init();
|
||||
|
||||
void ICACHE_FLASH_ATTR user_init() {
|
||||
// init gpio subsystem
|
||||
gpio_init();
|
||||
|
||||
// configure UART TXD to be GPIO1, set as output
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1);
|
||||
gpio_output_set(0, 0, (1 << pin), 0);
|
||||
|
||||
// configure SPI
|
||||
SpiAttr hSpiAttr;
|
||||
hSpiAttr.bitOrder = SpiBitOrder_MSBFirst;
|
||||
hSpiAttr.speed = SpiSpeed_10MHz;
|
||||
hSpiAttr.mode = SpiMode_Master;
|
||||
hSpiAttr.subMode = SpiSubMode_0;
|
||||
|
||||
// TODO: is one of these CS?
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2); // configure io to spi mode
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2); // configure io to spi mode
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2); // configure io to spi mode
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2); // configure io to spi mode
|
||||
SPIInit(SpiNum_HSPI, &hSpiAttr);
|
||||
//SPICsPinSelect(SpiNum_HSPI, SpiPinCS_1);
|
||||
|
||||
// configure UART TXD to be GPIO1, set as output
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5);
|
||||
gpio_output_set(0, 0, (1 << 5), 0);
|
||||
gpio_output_set((1 << 5), 0, 0, 0);
|
||||
|
||||
// uart init
|
||||
uart_init(BIT_RATE_115200, BIT_RATE_115200);
|
||||
|
||||
// led init
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
|
||||
gpio_output_set(0, (1 << pin), (1 << pin), 0);
|
||||
|
||||
os_printf("hello\n");
|
||||
|
||||
// needs SPI
|
||||
wifi_init();
|
||||
|
||||
// support ota upgrades
|
||||
elm327_init();
|
||||
web_init();
|
||||
|
||||
// set gpio high, so LED is off by default
|
||||
for (int i = 0; i < 5; i++) {
|
||||
gpio_output_set(0, (1 << pin), 0, 0);
|
||||
os_delay_us(50000);
|
||||
gpio_output_set((1 << pin), 0, 0, 0);
|
||||
os_delay_us(50000);
|
||||
}
|
||||
|
||||
// jump to OS
|
||||
system_os_task(loop, LOOP_PRIO, my_queue, QUEUE_SIZE);
|
||||
system_os_post(LOOP_PRIO, 0, 0);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR loop(os_event_t *events) {
|
||||
system_os_post(LOOP_PRIO, 0, 0);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/usr/bin/env python2
|
||||
import os
|
||||
import sys
|
||||
os.system(sys.argv[1])
|
|
@ -1,380 +0,0 @@
|
|||
#include "stdlib.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "gpio.h"
|
||||
#include "mem.h"
|
||||
#include "os_type.h"
|
||||
#include "user_interface.h"
|
||||
#include "espconn.h"
|
||||
#include "upgrade.h"
|
||||
|
||||
#include "crypto/rsa.h"
|
||||
#include "crypto/sha.h"
|
||||
|
||||
#include "obj/gitversion.h"
|
||||
#include "obj/cert.h"
|
||||
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define espconn_send_string(conn, x) espconn_send(conn, x, strlen(x))
|
||||
|
||||
#define MAX_RESP 0x800
|
||||
char resp[MAX_RESP];
|
||||
char pageheader[] = "HTTP/1.0 200 OK\nContent-Type: text/html\n\n"
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>Panda</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<pre>This is your comma.ai panda\n\n"
|
||||
"It's open source. Find the code <a href=\"https://github.com/commaai/panda\">here</a>\n";
|
||||
|
||||
char pagefooter[] = "</pre>\n"
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
char OK_header[] = "HTTP/1.0 200 OK\nContent-Type: text/html\n\n";
|
||||
|
||||
static struct espconn web_conn;
|
||||
static esp_tcp web_proto;
|
||||
extern char ssid[];
|
||||
extern int wifi_secure_mode;
|
||||
|
||||
char *st_firmware;
|
||||
int real_content_length, content_length = 0;
|
||||
char *st_firmware_ptr;
|
||||
LOCAL os_timer_t ota_reboot_timer;
|
||||
|
||||
#define FIRMWARE_SIZE 503808
|
||||
|
||||
typedef struct {
|
||||
uint16_t ep;
|
||||
uint16_t extra_len;
|
||||
union {
|
||||
struct {
|
||||
uint8_t request_type;
|
||||
uint8_t request;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint16_t length;
|
||||
} control;
|
||||
uint8_t data[0x10];
|
||||
} u;
|
||||
} usb_msg;
|
||||
|
||||
int ICACHE_FLASH_ATTR usb_cmd(int ep, int len, int request,
|
||||
int value, int index, char *data) {
|
||||
usb_msg usb = {0};
|
||||
|
||||
usb.ep = ep;
|
||||
usb.extra_len = (ep == 0) ? 0 : len;
|
||||
if (ep == 0) {
|
||||
usb.u.control.request_type = 0xc0;
|
||||
usb.u.control.request = request;
|
||||
usb.u.control.value = value;
|
||||
usb.u.control.index = index;
|
||||
} else {
|
||||
memcpy(&usb.u.data, data, usb.extra_len);
|
||||
}
|
||||
|
||||
uint32_t recv[0x44/4];
|
||||
spi_comm(&usb, sizeof(usb), recv, 0x40);
|
||||
|
||||
return recv[0];
|
||||
}
|
||||
|
||||
|
||||
void ICACHE_FLASH_ATTR st_flash() {
|
||||
if (st_firmware != NULL) {
|
||||
// boot mode
|
||||
os_printf("st_flash: enter boot mode\n");
|
||||
st_set_boot_mode(1);
|
||||
|
||||
// echo
|
||||
os_printf("st_flash: wait for echo\n");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
os_printf(" attempt: %d\n", i);
|
||||
if (usb_cmd(0, 0, 0xb0, 0, 0, NULL) > 0) break;
|
||||
}
|
||||
|
||||
// unlock flash
|
||||
os_printf("st_flash: unlock flash\n");
|
||||
usb_cmd(0, 0, 0xb1, 0, 0, NULL);
|
||||
|
||||
// erase sector 1
|
||||
os_printf("st_flash: erase sector 1\n");
|
||||
usb_cmd(0, 0, 0xb2, 1, 0, NULL);
|
||||
|
||||
if (real_content_length >= 16384) {
|
||||
// erase sector 2
|
||||
os_printf("st_flash: erase sector 2\n");
|
||||
usb_cmd(0, 0, 0xb2, 2, 0, NULL);
|
||||
}
|
||||
|
||||
// real content length will always be 0x10 aligned
|
||||
os_printf("st_flash: flashing\n");
|
||||
for (int i = 0; i < real_content_length; i += 0x10) {
|
||||
int rl = MIN(0x10, real_content_length-i);
|
||||
usb_cmd(2, rl, 0, 0, 0, &st_firmware[i]);
|
||||
system_soft_wdt_feed();
|
||||
}
|
||||
|
||||
// reboot into normal mode
|
||||
os_printf("st_flash: rebooting\n");
|
||||
usb_cmd(0, 0, 0xd8, 0, 0, NULL);
|
||||
|
||||
// done with this
|
||||
os_free(st_firmware);
|
||||
st_firmware = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
NOT_STARTED,
|
||||
CONNECTION_ESTABLISHED,
|
||||
RECEIVING_HEADER,
|
||||
RECEIVING_ST_FIRMWARE,
|
||||
RECEIVING_ESP_FIRMWARE,
|
||||
REBOOTING,
|
||||
ERROR
|
||||
} web_state_t;
|
||||
|
||||
web_state_t state = NOT_STARTED;
|
||||
int esp_address, esp_address_erase_limit, start_address;
|
||||
|
||||
void ICACHE_FLASH_ATTR hexdump(char *data, int len) {
|
||||
int i;
|
||||
for (i=0;i<len;i++) {
|
||||
if (i!=0 && (i%0x10)==0) os_printf("\n");
|
||||
os_printf("%02X ", data[i]);
|
||||
}
|
||||
os_printf("\n");
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR st_reset() {
|
||||
// reset the ST
|
||||
gpio16_output_conf();
|
||||
gpio16_output_set(0);
|
||||
os_delay_us(1000);
|
||||
gpio16_output_set(1);
|
||||
os_delay_us(10000);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR st_set_boot_mode(int boot_mode) {
|
||||
if (boot_mode) {
|
||||
// boot mode (pull low)
|
||||
gpio_output_set(0, (1 << 4), (1 << 4), 0);
|
||||
st_reset();
|
||||
} else {
|
||||
// no boot mode (pull high)
|
||||
gpio_output_set((1 << 4), 0, (1 << 4), 0);
|
||||
st_reset();
|
||||
}
|
||||
|
||||
// float boot pin
|
||||
gpio_output_set(0, 0, 0, (1 << 4));
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR web_rx_cb(void *arg, char *data, uint16_t len) {
|
||||
int i;
|
||||
struct espconn *conn = (struct espconn *)arg;
|
||||
if (state == CONNECTION_ESTABLISHED) {
|
||||
state = RECEIVING_HEADER;
|
||||
os_printf("%s %d\n", data, len);
|
||||
|
||||
// index
|
||||
if (memcmp(data, "GET / ", 6) == 0) {
|
||||
memset(resp, 0, MAX_RESP);
|
||||
|
||||
strcpy(resp, pageheader);
|
||||
ets_strcat(resp, "\nssid: ");
|
||||
ets_strcat(resp, ssid);
|
||||
ets_strcat(resp, "\n");
|
||||
|
||||
ets_strcat(resp, "\nst version: ");
|
||||
uint32_t recvData[0x11];
|
||||
int len = spi_comm("\x00\x00\x00\x00\x40\xD6\x00\x00\x00\x00\x40\x00", 0xC, recvData, 0x40);
|
||||
ets_memcpy(resp+strlen(resp), recvData+1, len);
|
||||
|
||||
ets_strcat(resp, "\nesp version: ");
|
||||
ets_strcat(resp, gitversion);
|
||||
uint8_t current = system_upgrade_userbin_check();
|
||||
if (current == UPGRADE_FW_BIN1) {
|
||||
ets_strcat(resp, "\nesp flash file: user2.bin");
|
||||
} else {
|
||||
ets_strcat(resp, "\nesp flash file: user1.bin");
|
||||
}
|
||||
|
||||
if (wifi_secure_mode) {
|
||||
ets_strcat(resp, "\nin secure mode");
|
||||
} else {
|
||||
ets_strcat(resp, "\nin INSECURE mode...<a href=\"/secure\">secure it</a>");
|
||||
}
|
||||
|
||||
ets_strcat(resp,"\nSet USB Mode:"
|
||||
"<button onclick=\"var xhr = new XMLHttpRequest(); xhr.open('GET', 'set_property?usb_mode=0'); xhr.send()\" type='button'>Client</button>"
|
||||
"<button onclick=\"var xhr = new XMLHttpRequest(); xhr.open('GET', 'set_property?usb_mode=1'); xhr.send()\" type='button'>CDP</button>"
|
||||
"<button onclick=\"var xhr = new XMLHttpRequest(); xhr.open('GET', 'set_property?usb_mode=2'); xhr.send()\" type='button'>DCP</button>\n");
|
||||
|
||||
ets_strcat(resp, pagefooter);
|
||||
|
||||
espconn_send_string(&web_conn, resp);
|
||||
espconn_disconnect(conn);
|
||||
} else if (memcmp(data, "GET /secure", 11) == 0 && !wifi_secure_mode) {
|
||||
wifi_configure(1);
|
||||
} else if (memcmp(data, "GET /set_property?usb_mode=", 27) == 0 && wifi_secure_mode) {
|
||||
char mode_value = data[27] - '0';
|
||||
if (mode_value >= '\x00' && mode_value <= '\x02') {
|
||||
memset(resp, 0, MAX_RESP);
|
||||
char set_usb_mode_packet[] = "\x00\x00\x00\x00\x40\xE6\x00\x00\x00\x00\x40\x00";
|
||||
set_usb_mode_packet[6] = mode_value;
|
||||
uint32_t recvData[1];
|
||||
spi_comm(set_usb_mode_packet, 0xC, recvData, 0);
|
||||
os_sprintf(resp, "%sUSB Mode set to %02x\n\n", OK_header, mode_value);
|
||||
espconn_send_string(&web_conn, resp);
|
||||
espconn_disconnect(conn);
|
||||
}
|
||||
} else if (memcmp(data, "PUT /stupdate ", 14) == 0 && wifi_secure_mode) {
|
||||
os_printf("init st firmware\n");
|
||||
char *cl = strstr(data, "Content-Length: ");
|
||||
if (cl != NULL) {
|
||||
// get content length
|
||||
cl += strlen("Content-Length: ");
|
||||
content_length = skip_atoi(&cl);
|
||||
os_printf("with content length %d\n", content_length);
|
||||
|
||||
// should be small enough to fit in RAM
|
||||
real_content_length = (content_length+0xF)&(~0xF);
|
||||
st_firmware_ptr = st_firmware = os_malloc(real_content_length);
|
||||
memset(st_firmware, 0, real_content_length);
|
||||
state = RECEIVING_ST_FIRMWARE;
|
||||
}
|
||||
|
||||
} else if (((memcmp(data, "PUT /espupdate1 ", 16) == 0) ||
|
||||
(memcmp(data, "PUT /espupdate2 ", 16) == 0)) && wifi_secure_mode) {
|
||||
// 0x1000 = user1.bin
|
||||
// 0x81000 = user2.bin
|
||||
// 0x3FE000 = blank.bin
|
||||
os_printf("init esp firmware\n");
|
||||
char *cl = strstr(data, "Content-Length: ");
|
||||
if (cl != NULL) {
|
||||
// get content length
|
||||
cl += strlen("Content-Length: ");
|
||||
content_length = skip_atoi(&cl);
|
||||
os_printf("with content length %d\n", content_length);
|
||||
|
||||
// setup flashing
|
||||
uint8_t current = system_upgrade_userbin_check();
|
||||
if (data[14] == '2' && current == UPGRADE_FW_BIN1) {
|
||||
os_printf("flashing boot2.bin\n");
|
||||
state = RECEIVING_ESP_FIRMWARE;
|
||||
esp_address = 4*1024 + FIRMWARE_SIZE + 16*1024 + 4*1024;
|
||||
} else if (data[14] == '1' && current == UPGRADE_FW_BIN2) {
|
||||
os_printf("flashing boot1.bin\n");
|
||||
state = RECEIVING_ESP_FIRMWARE;
|
||||
esp_address = 4*1024;
|
||||
} else {
|
||||
espconn_send_string(&web_conn, "HTTP/1.0 404 Not Found\nContent-Type: text/html\n\nwrong!\n");
|
||||
espconn_disconnect(conn);
|
||||
}
|
||||
esp_address_erase_limit = esp_address;
|
||||
start_address = esp_address;
|
||||
}
|
||||
} else {
|
||||
espconn_send_string(&web_conn, "HTTP/1.0 404 Not Found\nContent-Type: text/html\n\n404 Not Found!\n");
|
||||
espconn_disconnect(conn);
|
||||
}
|
||||
} else if (state == RECEIVING_ST_FIRMWARE) {
|
||||
os_printf("receiving st firmware: %d/%d\n", len, content_length);
|
||||
memcpy(st_firmware_ptr, data, MIN(content_length, len));
|
||||
st_firmware_ptr += len;
|
||||
content_length -= len;
|
||||
|
||||
if (content_length <= 0 && real_content_length > 1000) {
|
||||
state = NOT_STARTED;
|
||||
os_printf("done!\n");
|
||||
espconn_send_string(&web_conn, "HTTP/1.0 200 OK\nContent-Type: text/html\n\nsuccess!\n");
|
||||
espconn_disconnect(conn);
|
||||
|
||||
// reboot
|
||||
os_printf("Scheduling st_flash in 100ms.\n");
|
||||
os_timer_disarm(&ota_reboot_timer);
|
||||
os_timer_setfn(&ota_reboot_timer, (os_timer_func_t *)st_flash, NULL);
|
||||
os_timer_arm(&ota_reboot_timer, 100, 0);
|
||||
}
|
||||
} else if (state == RECEIVING_ESP_FIRMWARE) {
|
||||
if ((esp_address+len) < (start_address + FIRMWARE_SIZE)) {
|
||||
os_printf("receiving esp firmware: %d/%d -- 0x%x - 0x%x\n", len, content_length,
|
||||
esp_address, esp_address_erase_limit);
|
||||
content_length -= len;
|
||||
while (esp_address_erase_limit < (esp_address + len)) {
|
||||
os_printf("erasing 0x%X\n", esp_address_erase_limit);
|
||||
spi_flash_erase_sector(esp_address_erase_limit / SPI_FLASH_SEC_SIZE);
|
||||
esp_address_erase_limit += SPI_FLASH_SEC_SIZE;
|
||||
}
|
||||
SpiFlashOpResult res = spi_flash_write(esp_address, data, len);
|
||||
if (res != SPI_FLASH_RESULT_OK) {
|
||||
os_printf("flash fail @ 0x%x\n", esp_address);
|
||||
}
|
||||
esp_address += len;
|
||||
|
||||
if (content_length == 0) {
|
||||
|
||||
char digest[SHA_DIGEST_SIZE];
|
||||
uint32_t rsa[RSANUMBYTES/4];
|
||||
uint32_t dat[0x80/4];
|
||||
int ll;
|
||||
spi_flash_read(esp_address-RSANUMBYTES, rsa, RSANUMBYTES);
|
||||
|
||||
// 32-bit aligned accesses only
|
||||
SHA_CTX ctx;
|
||||
SHA_init(&ctx);
|
||||
for (ll = start_address; ll < esp_address-RSANUMBYTES; ll += 0x80) {
|
||||
spi_flash_read(ll, dat, 0x80);
|
||||
SHA_update(&ctx, dat, MIN((esp_address-RSANUMBYTES)-ll, 0x80));
|
||||
}
|
||||
memcpy(digest, SHA_final(&ctx), SHA_DIGEST_SIZE);
|
||||
|
||||
if (RSA_verify(&releaseesp_rsa_key, rsa, RSANUMBYTES, digest, SHA_DIGEST_SIZE) ||
|
||||
#ifdef ALLOW_DEBUG
|
||||
RSA_verify(&debugesp_rsa_key, rsa, RSANUMBYTES, digest, SHA_DIGEST_SIZE)
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
) {
|
||||
os_printf("RSA verify success!\n");
|
||||
espconn_send_string(&web_conn, "HTTP/1.0 200 OK\nContent-Type: text/html\n\nsuccess!\n");
|
||||
system_upgrade_flag_set(UPGRADE_FLAG_FINISH);
|
||||
|
||||
// reboot
|
||||
os_printf("Scheduling reboot.\n");
|
||||
os_timer_disarm(&ota_reboot_timer);
|
||||
os_timer_setfn(&ota_reboot_timer, (os_timer_func_t *)system_upgrade_reboot, NULL);
|
||||
os_timer_arm(&ota_reboot_timer, 2000, 0);
|
||||
} else {
|
||||
os_printf("RSA verify FAILURE\n");
|
||||
espconn_send_string(&web_conn, "HTTP/1.0 500 Internal Server Error\nContent-Type: text/html\n\nrsa verify fail\n");
|
||||
}
|
||||
espconn_disconnect(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR web_tcp_connect_cb(void *arg) {
|
||||
state = CONNECTION_ESTABLISHED;
|
||||
struct espconn *conn = (struct espconn *)arg;
|
||||
espconn_set_opt(&web_conn, ESPCONN_NODELAY);
|
||||
espconn_regist_recvcb(conn, web_rx_cb);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR web_init() {
|
||||
web_proto.local_port = 80;
|
||||
web_conn.type = ESPCONN_TCP;
|
||||
web_conn.state = ESPCONN_NONE;
|
||||
web_conn.proto.tcp = &web_proto;
|
||||
espconn_regist_connectcb(&web_conn, web_tcp_connect_cb);
|
||||
espconn_accept(&web_conn);
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCjIHvrSCWN0Nec6ozbImYik30PIF7JSWgdwDKTxSJ05RM3pj5E
|
||||
LQEGt3qcaVrTokO68tpt5Gu1p6ZsNqWg7iVTW9M7Qj7IH45YDzQP/PSRjgSosQA6
|
||||
6f5Gokba5QrW38myqimvj+0p+YH+CNGCBRlTUQGCO8uLCspMZneRSLPW9QIDAQAB
|
||||
AoGADaUn+HRef9BaWMvd4G6uMHI54cwJYbj8NpDfKjExQqnuw5bqWnWRQmiSnwbJ
|
||||
DC7kj3zE/LBAuj890ot3q1CAWqh47ZICZfoX9Qbi5TpvIHFCGy6YkOliF6iIQhR2
|
||||
4+zNKTAA0zNKskOM25PdI+grK1Ni/bEofSA6TrqvEwsmxnkCQQDVp9FUUor2Bo/h
|
||||
/3oAIP51LTw7vfpztYbJr+BDV63czV2DLXzSwzeNrwH4sA3oy1mjUgMBBgAarNGE
|
||||
DYlc4H5jAkEAw3UCHzzXPlxkw2QGp7nBly5y3p80Uqc31NuYz8rdX/U8KTngi2No
|
||||
Ft/SGCEXNpeYbToj+WK3RJJ2Ey0mK8+IxwJAcpGd/5CPsaQNLcw4WK9Yo+8Q2Jxk
|
||||
G/4gfDCSmqn+smNxnLEcuUwzkwdgkEGgA9BfjeOhdsAH+EXpx90WZrZ/LwJBAK0k
|
||||
jq+rTqUQZbZsejTEKYjJ/bnV4BzDwoKN0Q1pkLc7X4LJoW74rTFuLgdv8MdMfRtt
|
||||
IIb/eoeFEpGkMicnHesCQHgR7BTUGBM6Uxam7RCdsgVsxoHBma21E/44ivWUMZzN
|
||||
3oVt0mPnjS4speOlqwED5pCJ7yw7jwLPFMs8kNxuIKU=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCjIHvrSCWN0Nec6ozbImYik30PIF7JSWgdwDKTxSJ05RM3pj5ELQEGt3qcaVrTokO68tpt5Gu1p6ZsNqWg7iVTW9M7Qj7IH45YDzQP/PSRjgSosQA66f5Gokba5QrW38myqimvj+0p+YH+CNGCBRlTUQGCO8uLCspMZneRSLPW9Q== batman@y840
|
|
@ -1 +0,0 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDN4pVyGuJJSde1l3Fjay8qPxog09DsAJZtYPk+armoYO1L6YKReUTcMNyHQYZZMZFmhCdgjCgTIF2QYWMoP4KSe8l6JF04YPP51dIgefc6UXjtlSI8Pyutr0v9xXjSfsVm3RAJxDSHgzs9AoMsluKCL+LhAR1nd7cuHXITJ80O4w== batman@y840
|
|
@ -1,16 +0,0 @@
|
|||
# Connecting to White Panda via Wi-Fi
|
||||
|
||||
1. First connect to your White Panda's Wi-Fi pairing network (this should be the Wi-Fi network WITH the "-pair" at the end)
|
||||
|
||||
2. Now in your favorite web browser go to this address **192.168.0.10** (this should open a web interface to interact with the White Panda)
|
||||
|
||||
3. Inside the web interface enable secured mode by clinking the **secure it** link/button (this should make the White Panda's Wi-Fi network visible)
|
||||
|
||||
### If you need your White Panda's Wi-Fi Password
|
||||
|
||||
* Run the **get_panda_password.py** script in found in **examples/** (Must have panda paw for this step because you need to connect White Panda via USB to retrive the Wi-Fi password)
|
||||
* Also ensure that you are connected to your White Panda's Wi-Fi pairing network
|
||||
|
||||
4. Connect to your White Panda's default Wi-Fi network (this should be the Wi-Fi network WITHOUT the "-pair" at the end)
|
||||
|
||||
5. Your White Panda is now connected to Wi-Fi you can test this by running this line of code `python -c 'from panda import Panda; panda = Panda("WIFI")'` in your terminal of choice.
|
|
@ -10,7 +10,6 @@ import traceback
|
|||
import subprocess
|
||||
import sys
|
||||
from .dfu import PandaDFU # pylint: disable=import-error
|
||||
from .esptool import ESPROM, CesantaFlasher # noqa pylint: disable=import-error
|
||||
from .flash_release import flash_release # noqa pylint: disable=import-error
|
||||
from .update import ensure_st_up_to_date # noqa pylint: disable=import-error
|
||||
from .serial import PandaSerial # noqa pylint: disable=import-error
|
||||
|
|
1317
python/esptool.py
1317
python/esptool.py
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,7 @@ import json
|
|||
import io
|
||||
|
||||
def flash_release(path=None, st_serial=None):
|
||||
from panda import Panda, PandaDFU, ESPROM, CesantaFlasher
|
||||
from panda import Panda, PandaDFU
|
||||
from zipfile import ZipFile
|
||||
|
||||
def status(x):
|
||||
|
@ -43,9 +43,6 @@ def flash_release(path=None, st_serial=None):
|
|||
code_boot_15 = zf.read("boot_v1.5.bin")
|
||||
code_boot_15 = code_boot_15[0:2] + "\x00\x30" + code_boot_15[4:]
|
||||
|
||||
code_user1 = zf.read("user1.bin")
|
||||
code_user2 = zf.read("user2.bin")
|
||||
|
||||
# enter DFU mode
|
||||
status("1. Entering DFU mode")
|
||||
panda = Panda(st_serial)
|
||||
|
@ -64,29 +61,8 @@ def flash_release(path=None, st_serial=None):
|
|||
panda.flash(code=code_panda)
|
||||
panda.close()
|
||||
|
||||
# flashing ESP
|
||||
if panda.is_white():
|
||||
status("4. Flashing ESP (slow!)")
|
||||
|
||||
def align(x, sz=0x1000):
|
||||
x + "\xFF" * ((sz - len(x)) % sz)
|
||||
|
||||
esp = ESPROM(st_serial)
|
||||
esp.connect()
|
||||
flasher = CesantaFlasher(esp, 230400)
|
||||
flasher.flash_write(0x0, align(code_boot_15), True)
|
||||
flasher.flash_write(0x1000, align(code_user1), True)
|
||||
flasher.flash_write(0x81000, align(code_user2), True)
|
||||
flasher.flash_write(0x3FE000, "\xFF" * 0x1000)
|
||||
flasher.boot_fw()
|
||||
del flasher
|
||||
del esp
|
||||
time.sleep(1)
|
||||
else:
|
||||
status("4. No ESP in non-white panda")
|
||||
|
||||
# check for connection
|
||||
status("5. Verifying version")
|
||||
status("4. Verifying version")
|
||||
panda = Panda(st_serial)
|
||||
my_version = panda.get_version()
|
||||
print("dongle id: %s" % panda.get_serial()[0])
|
||||
|
|
|
@ -6,11 +6,7 @@ else
|
|||
TESTSUITE_NAME="Panda_Test-DEV"
|
||||
fi
|
||||
|
||||
if [ ! -z "${SKIPWIFI}" ] || [ -f "/EON" ]; then
|
||||
TEST_SCRIPTS=$(ls tests/automated/$1*.py | grep -v wifi)
|
||||
else
|
||||
TEST_SCRIPTS=$(ls tests/automated/$1*.py)
|
||||
fi
|
||||
TEST_SCRIPTS=$(ls tests/automated/$1*.py)
|
||||
|
||||
IFS=$'\n'
|
||||
for NAME in $(nmcli --fields NAME con show | grep panda | awk '{$1=$1};1')
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
import requests
|
||||
import json
|
||||
from .automated.helpers import _connect_wifi # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
from nose.tools import assert_equal
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Fetching latest firmware from github.com/commaai/panda-artifacts")
|
||||
r = requests.get("https://raw.githubusercontent.com/commaai/panda-artifacts/master/latest.json")
|
||||
latest_version = json.loads(r.text)['version']
|
||||
|
||||
for p in Panda.list():
|
||||
dongle_id, pw = Panda(p).get_serial()
|
||||
print(dongle_id, pw)
|
||||
assert(dongle_id.isalnum())
|
||||
_connect_wifi(dongle_id, pw)
|
||||
|
||||
r = requests.get("http://192.168.0.10/")
|
||||
print(r.text)
|
||||
wifi_dongle_id = r.text.split("ssid: panda-")[1].split("<br/>")[0]
|
||||
st_version = r.text.split("st version:")[1].strip().split("<br/>")[0]
|
||||
esp_version = r.text.split("esp version:")[1].strip().split("<br/>")[0]
|
||||
|
||||
assert_equal(str(dongle_id), wifi_dongle_id)
|
||||
assert_equal(latest_version, st_version)
|
||||
assert_equal(latest_version, esp_version)
|
|
@ -1,60 +0,0 @@
|
|||
import time
|
||||
from panda import Panda
|
||||
from .helpers import reset_pandas, connect_wifi, test_white, test_all_pandas, panda_type_to_serial, panda_connect_and_init
|
||||
import requests
|
||||
|
||||
# Reset the pandas before running tests
|
||||
def aaaa_reset_before_tests():
|
||||
reset_pandas()
|
||||
|
||||
@test_all_pandas
|
||||
@panda_connect_and_init
|
||||
def test_get_serial(p):
|
||||
print(p.get_serial())
|
||||
|
||||
@test_all_pandas
|
||||
@panda_connect_and_init
|
||||
def test_get_serial_in_flash_mode(p):
|
||||
p.reset(enter_bootstub=True)
|
||||
assert(p.bootstub)
|
||||
print(p.get_serial())
|
||||
p.reset()
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
def test_connect_wifi(serials=None):
|
||||
connect_wifi(serials[0])
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
def test_flash_wifi(serials=None):
|
||||
connect_wifi(serials[0])
|
||||
assert Panda.flash_ota_wifi(release=False), "OTA Wifi Flash Failed"
|
||||
connect_wifi(serials[0])
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
def test_wifi_flash_st(serials=None):
|
||||
connect_wifi(serials[0])
|
||||
assert Panda.flash_ota_st(), "OTA ST Flash Failed"
|
||||
connected = False
|
||||
st = time.time()
|
||||
while not connected and (time.time() - st) < 20:
|
||||
try:
|
||||
p = Panda(serial=serials[0])
|
||||
p.get_serial()
|
||||
connected = True
|
||||
except:
|
||||
time.sleep(1)
|
||||
|
||||
if not connected:
|
||||
assert False, "Panda failed to connect on USB after flashing"
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
def test_webpage_fetch(serials=None):
|
||||
connect_wifi(serials[0])
|
||||
r = requests.get("http://192.168.0.10/")
|
||||
print(r.text)
|
||||
|
||||
assert "This is your comma.ai panda" in r.text
|
|
@ -1,69 +0,0 @@
|
|||
import time
|
||||
from panda import Panda
|
||||
from .helpers import start_heartbeat_thread, reset_pandas, time_many_sends, connect_wifi, test_white, panda_type_to_serial
|
||||
|
||||
# Reset the pandas before running tests
|
||||
def aaaa_reset_before_tests():
|
||||
reset_pandas()
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
def test_get_serial_wifi(serials=None):
|
||||
connect_wifi(serials[0])
|
||||
|
||||
p = Panda("WIFI")
|
||||
print(p.get_serial())
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
def test_throughput(serials=None):
|
||||
connect_wifi(serials[0])
|
||||
p = Panda(serials[0])
|
||||
|
||||
# Start heartbeat
|
||||
start_heartbeat_thread(p)
|
||||
|
||||
# enable output mode
|
||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
|
||||
# enable CAN loopback mode
|
||||
p.set_can_loopback(True)
|
||||
|
||||
p = Panda("WIFI")
|
||||
|
||||
for speed in [100, 250, 500, 750, 1000]:
|
||||
# set bus 0 speed to speed
|
||||
p.set_can_speed_kbps(0, speed)
|
||||
time.sleep(0.1)
|
||||
|
||||
comp_kbps = time_many_sends(p, 0)
|
||||
|
||||
# bit count from https://en.wikipedia.org/wiki/CAN_bus
|
||||
saturation_pct = (comp_kbps / speed) * 100.0
|
||||
#assert_greater(saturation_pct, 80)
|
||||
#assert_less(saturation_pct, 100)
|
||||
|
||||
print("WIFI loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct))
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
def test_recv_only(serials=None):
|
||||
connect_wifi(serials[0])
|
||||
p = Panda(serials[0])
|
||||
|
||||
# Start heartbeat
|
||||
start_heartbeat_thread(p)
|
||||
|
||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
|
||||
p.set_can_loopback(True)
|
||||
pwifi = Panda("WIFI")
|
||||
|
||||
# TODO: msg_count=1000 drops packets, is this fixable?
|
||||
for msg_count in [10, 100, 200]:
|
||||
speed = 500
|
||||
p.set_can_speed_kbps(0, speed)
|
||||
comp_kbps = time_many_sends(p, 0, pwifi, msg_count)
|
||||
saturation_pct = (comp_kbps / speed) * 100.0
|
||||
|
||||
print("HT WIFI loopback %d messages at speed %d, comp speed is %.2f, percent %.2f" % (msg_count, speed, comp_kbps, saturation_pct))
|
|
@ -1,73 +0,0 @@
|
|||
import sys
|
||||
import time
|
||||
from .helpers import start_heartbeat_thread, reset_pandas, time_many_sends, connect_wifi, test_white, panda_type_to_serial
|
||||
from panda import Panda, PandaWifiStreaming
|
||||
from nose.tools import assert_less, assert_greater
|
||||
|
||||
# Reset the pandas before running tests
|
||||
def aaaa_reset_before_tests():
|
||||
reset_pandas()
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
def test_udp_doesnt_drop(serials=None):
|
||||
connect_wifi(serials[0])
|
||||
|
||||
p = Panda(serials[0])
|
||||
|
||||
# Start heartbeat
|
||||
start_heartbeat_thread(p)
|
||||
|
||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
p.set_can_loopback(True)
|
||||
|
||||
pwifi = PandaWifiStreaming()
|
||||
while 1:
|
||||
if len(pwifi.can_recv()) == 0:
|
||||
break
|
||||
|
||||
for msg_count in [1, 100]:
|
||||
saturation_pcts = []
|
||||
for i in range({1: 0x80, 100: 0x20}[msg_count]):
|
||||
pwifi.kick()
|
||||
|
||||
speed = 500
|
||||
p.set_can_speed_kbps(0, speed)
|
||||
comp_kbps = time_many_sends(p, 0, pwifi, msg_count=msg_count, msg_id=0x100 + i)
|
||||
saturation_pct = (comp_kbps / speed) * 100.0
|
||||
|
||||
if msg_count == 1:
|
||||
sys.stdout.write(".")
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
print("UDP WIFI loopback %d messages at speed %d, comp speed is %.2f, percent %.2f" % (msg_count, speed, comp_kbps, saturation_pct))
|
||||
assert_greater(saturation_pct, 20) # sometimes the wifi can be slow...
|
||||
assert_less(saturation_pct, 100)
|
||||
saturation_pcts.append(saturation_pct)
|
||||
if len(saturation_pcts) > 0:
|
||||
assert_greater(sum(saturation_pcts) / len(saturation_pcts), 60)
|
||||
|
||||
time.sleep(5)
|
||||
usb_ok_cnt = 0
|
||||
REQ_USB_OK_CNT = 500
|
||||
st = time.time()
|
||||
msg_id = 0x1bb
|
||||
bus = 0
|
||||
last_missing_msg = 0
|
||||
while usb_ok_cnt < REQ_USB_OK_CNT and (time.time() - st) < 40:
|
||||
p.can_send(msg_id, "message", bus)
|
||||
time.sleep(0.01)
|
||||
r = [1]
|
||||
missing = True
|
||||
while len(r) > 0:
|
||||
r = p.can_recv()
|
||||
r = [x for x in r if x[3] == bus and x[0] == msg_id]
|
||||
if len(r) > 0:
|
||||
missing = False
|
||||
usb_ok_cnt += len(r)
|
||||
if missing:
|
||||
last_missing_msg = time.time()
|
||||
et = time.time() - st
|
||||
last_missing_msg = last_missing_msg - st
|
||||
print("waited {} for panda to recv can on usb, {} msgs, last missing at {}".format(et, usb_ok_cnt, last_missing_msg))
|
||||
assert usb_ok_cnt >= REQ_USB_OK_CNT, "Unable to recv can on USB after UDP"
|
|
@ -8,7 +8,6 @@ from panda_jungle import PandaJungle # pylint: disable=import-error
|
|||
from nose.tools import assert_equal
|
||||
from parameterized import parameterized, param
|
||||
from .timeout import run_with_timeout
|
||||
from .wifi_helpers import _connect_wifi
|
||||
|
||||
SPEED_NORMAL = 500
|
||||
SPEED_GMLAN = 33.3
|
||||
|
@ -70,13 +69,6 @@ test_uno = parameterized([
|
|||
param(panda_type=Panda.HW_TYPE_UNO)
|
||||
])
|
||||
|
||||
def connect_wifi(serial=None):
|
||||
p = Panda(serial=serial)
|
||||
p.set_esp_power(True)
|
||||
dongle_id, pw = p.get_serial()
|
||||
assert(dongle_id.isalnum())
|
||||
_connect_wifi(dongle_id, pw)
|
||||
|
||||
def time_many_sends(p, bus, p_recv=None, msg_count=100, msg_id=None, two_pandas=False):
|
||||
if p_recv == None:
|
||||
p_recv = p
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
import requests
|
||||
from panda import Panda
|
||||
FNULL = open(os.devnull, 'w')
|
||||
def _connect_wifi(dongle_id, pw, insecure_okay=False):
|
||||
ssid = "panda-" + dongle_id
|
||||
|
||||
r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT)
|
||||
if not r:
|
||||
# Can already ping, try connecting on wifi
|
||||
try:
|
||||
p = Panda("WIFI")
|
||||
p.get_serial()
|
||||
print("Already connected")
|
||||
return
|
||||
except:
|
||||
pass
|
||||
|
||||
print("WIFI: connecting to %s" % ssid)
|
||||
|
||||
while 1:
|
||||
if sys.platform == "darwin":
|
||||
os.system("networksetup -setairportnetwork en0 %s %s" % (ssid, pw))
|
||||
else:
|
||||
wlan_interface = subprocess.check_output(["sh", "-c", "iw dev | awk '/Interface/ {print $2}'"]).strip().decode('utf8')
|
||||
cnt = 0
|
||||
MAX_TRIES = 10
|
||||
while cnt < MAX_TRIES:
|
||||
print("WIFI: scanning %d" % cnt)
|
||||
os.system("iwlist %s scanning > /dev/null" % wlan_interface)
|
||||
os.system("nmcli device wifi rescan")
|
||||
wifi_networks = [x.decode("utf8") for x in subprocess.check_output(["nmcli", "dev", "wifi", "list"]).split(b"\n")]
|
||||
wifi_scan = [x for x in wifi_networks if ssid in x]
|
||||
if len(wifi_scan) != 0:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
# MAX_TRIES tries, ~10 seconds max
|
||||
cnt += 1
|
||||
assert cnt < MAX_TRIES
|
||||
if "-pair" in wifi_scan[0]:
|
||||
os.system("nmcli d wifi connect %s-pair" % (ssid))
|
||||
connect_cnt = 0
|
||||
MAX_TRIES = 100
|
||||
while connect_cnt < MAX_TRIES:
|
||||
connect_cnt += 1
|
||||
r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT)
|
||||
if r:
|
||||
print("Waiting for panda to ping...")
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
break
|
||||
if insecure_okay:
|
||||
break
|
||||
# fetch webpage
|
||||
print("connecting to insecure network to secure")
|
||||
try:
|
||||
r = requests.get("http://192.168.0.10/")
|
||||
except requests.ConnectionError:
|
||||
r = requests.get("http://192.168.0.10/")
|
||||
assert r.status_code == 200
|
||||
|
||||
print("securing")
|
||||
try:
|
||||
r = requests.get("http://192.168.0.10/secure", timeout=0.01)
|
||||
except requests.exceptions.Timeout:
|
||||
print("timeout http request to secure")
|
||||
pass
|
||||
else:
|
||||
ret = os.system("nmcli d wifi connect %s password %s" % (ssid, pw))
|
||||
if os.WEXITSTATUS(ret) == 0:
|
||||
#check ping too
|
||||
ping_ok = False
|
||||
connect_cnt = 0
|
||||
MAX_TRIES = 10
|
||||
while connect_cnt < MAX_TRIES:
|
||||
connect_cnt += 1
|
||||
r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT)
|
||||
if r:
|
||||
print("Waiting for panda to ping...")
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
ping_ok = True
|
||||
break
|
||||
if ping_ok:
|
||||
break
|
||||
|
||||
# TODO: confirm that it's connected to the right panda
|
|
@ -1,23 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi python python-pip gcc g++ git autoconf gperf bison flex automake texinfo wget help2man gawk libtool libtool-bin ncurses-dev unzip unrar-free libexpat-dev sed bzip2 locales curl zlib1g-dev libffi-dev libssl-dev python3 python3-pip
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN pip3 install pycryptodome==3.9.8
|
||||
|
||||
# Build esp toolchain
|
||||
RUN mkdir -p /panda/boardesp
|
||||
WORKDIR /panda/boardesp
|
||||
RUN git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
|
||||
WORKDIR /panda/boardesp/esp-open-sdk
|
||||
RUN git checkout 03f5e898a059451ec5f3de30e7feff30455f7ce
|
||||
COPY ./boardesp/python2_make.py /panda/boardesp/esp-open-sdk
|
||||
RUN python2 python2_make.py "CT_ALLOW_BUILD_AS_ROOT_SURE=1 make STANDALONE=y"
|
||||
|
||||
COPY . /panda
|
||||
|
||||
WORKDIR /panda
|
|
@ -1,3 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
from panda import Panda
|
||||
Panda().set_esp_power(False)
|
|
@ -1,669 +0,0 @@
|
|||
# flake8: noqa
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
import select
|
||||
import struct
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", ".."))
|
||||
from panda import Panda
|
||||
from panda.tests import elm_car_simulator
|
||||
|
||||
def elm_connect():
|
||||
s = socket.create_connection(("192.168.0.10", 35000))
|
||||
s.setblocking(0)
|
||||
return s
|
||||
|
||||
def read_or_fail(s):
|
||||
ready = select.select([s], [], [], 4)
|
||||
assert ready[0], "Socket did not receive data within the timeout duration."
|
||||
return s.recv(1000)
|
||||
|
||||
def sendrecv(s, dat):
|
||||
s.send(dat)
|
||||
return read_or_fail(s)
|
||||
|
||||
def send_compare(s, dat, ret, timeout=4):
|
||||
s.send(dat)
|
||||
res = b''
|
||||
while ret.startswith(res) and ret != res:
|
||||
print("Waiting")
|
||||
ready = select.select([s], [], [], timeout)
|
||||
if not ready[0]:
|
||||
print("current recv data:", repr(res))
|
||||
break
|
||||
res += s.recv(1000)
|
||||
#print("final recv data: '%s'" % repr(res))
|
||||
assert ret == res # , "Data does not agree (%s) (%s)"%(repr(ret), repr(res))
|
||||
|
||||
def sync_reset(s):
|
||||
s.send("ATZ\r")
|
||||
res = b''
|
||||
while not res.endswith("ELM327 v1.5\r\r>"):
|
||||
res += read_or_fail(s)
|
||||
print("Reset response is '%s'" % repr(res))
|
||||
|
||||
def test_reset():
|
||||
s = socket.create_connection(("192.168.0.10", 35000))
|
||||
s.setblocking(0)
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
def test_elm_cli():
|
||||
s = elm_connect()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
|
||||
send_compare(s, b'ATI\r', b'ATI\rELM327 v1.5\r\r>')
|
||||
|
||||
#Test Echo Off
|
||||
#Expected to be misimplimentation, but this is how the reference device behaved.
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Here is the odd part
|
||||
send_compare(s, b'ATE0\r', b'OK\r\r>') # Should prob show this immediately
|
||||
send_compare(s, b'ATI\r', b'ELM327 v1.5\r\r>')
|
||||
|
||||
#Test Newline On
|
||||
send_compare(s, b'ATL1\r', b'OK\r\n\r\n>')
|
||||
send_compare(s, b'ATI\r', b'ELM327 v1.5\r\n\r\n>')
|
||||
send_compare(s, b'ATL0\r', b'OK\r\r>')
|
||||
send_compare(s, b'ATI\r', b'ELM327 v1.5\r\r>')
|
||||
|
||||
send_compare(s, b'ATI\r', b'ELM327 v1.5\r\r>') # Test repeat command no echo
|
||||
send_compare(s, b'\r', b'ELM327 v1.5\r\r>')
|
||||
|
||||
send_compare(s, b'aTi\r', b'ELM327 v1.5\r\r>') # Test different case
|
||||
|
||||
send_compare(s, b' a T i\r', b'ELM327 v1.5\r\r>') # Test with white space
|
||||
|
||||
send_compare(s, b'ATCATHAT\r', b'?\r\r>') # Test Invalid AT command
|
||||
|
||||
send_compare(s, b'01 00 00 00 00 00 00 00\r', b'?\r\r>') # Test Invalid (too long) OBD command
|
||||
send_compare(s, b'01 GZ\r', b'?\r\r>') # Test Invalid (Non hex chars) OBD command
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
def test_elm_setget_protocol():
|
||||
s = elm_connect()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
|
||||
send_compare(s, b'ATSP0\r', b"OK\r\r>") # Set auto
|
||||
send_compare(s, b'ATDP\r', b"AUTO\r\r>")
|
||||
send_compare(s, b'ATDPN\r', b"A0\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set protocol
|
||||
send_compare(s, b'ATDP\r', b"ISO 15765-4 (CAN 11/500)\r\r>")
|
||||
send_compare(s, b'ATDPN\r', b"6\r\r>")
|
||||
|
||||
send_compare(s, b'ATSPA6\r', b"OK\r\r>") # Set auto with protocol default
|
||||
send_compare(s, b'ATDP\r', b"AUTO, ISO 15765-4 (CAN 11/500)\r\r>")
|
||||
send_compare(s, b'ATDPN\r', b"A6\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP7\r', b"OK\r\r>")
|
||||
send_compare(s, b'ATDP\r', b"ISO 15765-4 (CAN 29/500)\r\r>")
|
||||
send_compare(s, b'ATDPN\r', b"7\r\r>") # Test Does not accept invalid protocols
|
||||
send_compare(s, b'ATSPD\r', b"?\r\r>")
|
||||
send_compare(s, b'ATDP\r', b"ISO 15765-4 (CAN 29/500)\r\r>")
|
||||
send_compare(s, b'ATDPN\r', b"7\r\r>")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
def test_elm_protocol_failure():
|
||||
s = elm_connect()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
|
||||
send_compare(s, b'ATSP0\r', b"OK\r\r>")
|
||||
send_compare(s, b'0100\r', b"SEARCHING...\rUNABLE TO CONNECT\r\r>", timeout=10)
|
||||
|
||||
send_compare(s, b'ATSP1\r', b"OK\r\r>")
|
||||
send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP2\r', b"OK\r\r>")
|
||||
send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP3\r', b"OK\r\r>")
|
||||
send_compare(s, b'0100\r', b"BUS INIT: ...ERROR\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP4\r', b"OK\r\r>")
|
||||
send_compare(s, b'0100\r', b"BUS INIT: ...ERROR\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP5\r', b"OK\r\r>")
|
||||
send_compare(s, b'0100\r', b"BUS INIT: ERROR\r\r>")
|
||||
|
||||
#send_compare(s, b'ATSP6\r', b"OK\r\r>")
|
||||
#send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
#
|
||||
#send_compare(s, b'ATSP7\r', b"OK\r\r>")
|
||||
#send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
#
|
||||
#send_compare(s, b'ATSP8\r', b"OK\r\r>")
|
||||
#send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
#
|
||||
#send_compare(s, b'ATSP9\r', b"OK\r\r>")
|
||||
#send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
#
|
||||
#send_compare(s, b'ATSPA\r', b"OK\r\r>")
|
||||
#send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
#
|
||||
#send_compare(s, b'ATSPB\r', b"OK\r\r>")
|
||||
#send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
#
|
||||
#send_compare(s, b'ATSPC\r', b"OK\r\r>")
|
||||
#send_compare(s, b'0100\r', b"NO DATA\r\r>")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
def test_elm_protocol_autodetect_ISO14230_KWP_FAST():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, can=False) # , silent=True)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATH0\r', b'OK\r\r>') # Headers ON
|
||||
send_compare(s, b'ATS0\r', b"OK\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP0\r', b"OK\r\r>")
|
||||
send_compare(s, b'010D\r', b"SEARCHING...\r410D53\r\r>", timeout=10)
|
||||
send_compare(s, b'ATDPN\r', b"A5\r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_basic_send_lin():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, can=False) # , silent=True)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATSP5\r', b"ATSP5\rOK\r\r>") # Set Proto
|
||||
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'0100\r', b"BUS INIT: OK\r41 00 FF FF FF FE \r\r>")
|
||||
send_compare(s, b'010D\r', b"41 0D 53 \r\r>")
|
||||
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces Off
|
||||
send_compare(s, b'0100\r', b"4100FFFFFFFE\r\r>")
|
||||
send_compare(s, b'010D\r', b"410D53\r\r>")
|
||||
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Spaces Off Headers On
|
||||
send_compare(s, b'0100\r', b"86F1104100FFFFFFFEC3\r\r>")
|
||||
send_compare(s, b'010D\r', b"83F110410D5325\r\r>")
|
||||
|
||||
send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces On Headers On
|
||||
send_compare(s, b'0100\r', b"86 F1 10 41 00 FF FF FF FE C3 \r\r>")
|
||||
send_compare(s, b'010D\r', b"83 F1 10 41 0D 53 25 \r\r>")
|
||||
|
||||
send_compare(s, b'1F00\r', b"NO DATA\r\r>") # Unhandled msg, no response.
|
||||
|
||||
# Repeat last check to see if it still works after NO DATA was received
|
||||
send_compare(s, b'0100\r', b"86 F1 10 41 00 FF FF FF FE C3 \r\r>")
|
||||
send_compare(s, b'010D\r', b"83 F1 10 41 0D 53 25 \r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_send_lin_multiline_msg():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, can=False)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATSP5\r', b"OK\r\r>") # Set Proto
|
||||
|
||||
send_compare(s, b'0902\r', # headers OFF, Spaces ON
|
||||
b"BUS INIT: OK\r"
|
||||
b"49 02 01 00 00 00 31 \r"
|
||||
b"49 02 02 44 34 47 50 \r"
|
||||
b"49 02 03 30 30 52 35 \r"
|
||||
b"49 02 04 35 42 31 32 \r"
|
||||
b"49 02 05 33 34 35 36 \r\r>")
|
||||
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'0902\r', # Headers OFF, Spaces OFF
|
||||
b"49020100000031\r"
|
||||
b"49020244344750\r"
|
||||
b"49020330305235\r"
|
||||
b"49020435423132\r"
|
||||
b"49020533343536\r\r>")
|
||||
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
|
||||
send_compare(s, b'0902\r', # Headers ON, Spaces OFF
|
||||
b"87F1104902010000003105\r"
|
||||
b"87F11049020244344750E4\r"
|
||||
b"87F11049020330305235BD\r"
|
||||
b"87F11049020435423132B1\r"
|
||||
b"87F11049020533343536AA\r\r>")
|
||||
|
||||
send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces ON
|
||||
send_compare(s, b'0902\r', # Headers ON, Spaces ON
|
||||
b"87 F1 10 49 02 01 00 00 00 31 05 \r"
|
||||
b"87 F1 10 49 02 02 44 34 47 50 E4 \r"
|
||||
b"87 F1 10 49 02 03 30 30 52 35 BD \r"
|
||||
b"87 F1 10 49 02 04 35 42 31 32 B1 \r"
|
||||
b"87 F1 10 49 02 05 33 34 35 36 AA \r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_send_lin_multiline_msg_throughput():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, can=False, silent=True)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATSP5\r', b"ATSP5\rOK\r\r>") # Set Proto
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'ATH0\r', b'OK\r\r>') # Headers OFF
|
||||
|
||||
send_compare(s, b'09fc\r', # headers OFF, Spaces OFF
|
||||
b"BUS INIT: OK\r" +
|
||||
b''.join((b'49FC' + hex(num + 1)[2:].upper().zfill(2) +
|
||||
b'AAAA' + hex(num + 1)[2:].upper().zfill(4) + b'\r'
|
||||
for num in range(80))) +
|
||||
b"\r>",
|
||||
timeout=10
|
||||
)
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_panda_safety_mode_KWPFast():
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
p_car = Panda(serial) # Configure this so the messages will send
|
||||
p_car.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
p_car.kline_drain()
|
||||
|
||||
p_elm = Panda("WIFI")
|
||||
p_elm.set_safety_mode(Panda.SAFETY_ELM327)
|
||||
|
||||
def get_checksum(dat):
|
||||
result = 0
|
||||
result += sum(map(ord, dat)) if isinstance(b'dat', str) else sum(dat)
|
||||
return struct.pack("B", result % 0x100)
|
||||
|
||||
def timed_recv_check(p, bus, goodmsg):
|
||||
t = time.time()
|
||||
msg = bytearray()
|
||||
|
||||
while time.time() - t < 0.5 and len(msg) != len(goodmsg):
|
||||
msg += p._handle.controlRead(Panda.REQUEST_OUT, 0xe0, bus, 0, len(goodmsg) - len(msg))
|
||||
#print("Received", repr(msg))
|
||||
if msg == goodmsg:
|
||||
return True
|
||||
time.sleep(0.01)
|
||||
return False
|
||||
|
||||
def kline_send(p, x, bus=2):
|
||||
p.kline_drain(bus=bus)
|
||||
p._handle.bulkWrite(2, bytes([bus]) + x)
|
||||
return timed_recv_check(p, bus, x)
|
||||
|
||||
def did_send(priority, toaddr, fromaddr, dat, bus=2, checkbyte=None):
|
||||
msgout = struct.pack("BBB", priority | len(dat), toaddr, fromaddr) + dat
|
||||
msgout += get_checksum(msgout) if checkbyte is None else checkbyte
|
||||
print("Sending", hex(priority), hex(toaddr), hex(fromaddr), repr(msgout))
|
||||
|
||||
if not kline_send(p_elm, msgout, bus=bus):
|
||||
return False
|
||||
return timed_recv_check(p_car, bus, msgout)
|
||||
|
||||
assert not did_send(0xC0, 0x33, 0xF1, b'\x01\x0F', bus=3) # wrong bus
|
||||
assert not did_send(0xC0, 0x33, 0xF1, b'') # wrong length
|
||||
assert not did_send(0xB0, 0x33, 0xF1, b'\x01\x0E') # bad priority
|
||||
assert not did_send(0xC0, 0x00, 0xF1, b'\x01\x0D') # bad addr
|
||||
assert not did_send(0xC0, 0x33, 0x00, b'\x01\x0C') # bad addr
|
||||
|
||||
assert did_send(0xC0, 0x33, 0xF1, b'\x01\x0B') # good! (obd func req)
|
||||
|
||||
def test_elm_lin_keepalive():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, can=False, silent=True)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATSP5\r', b"ATSP5\rOK\r\r>") # Set Proto
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'ATH0\r', b'OK\r\r>') # Headers OFF
|
||||
|
||||
send_compare(s, b'0100\r', b"BUS INIT: OK\r4100FFFFFFFE\r\r>")
|
||||
assert sim.lin_active
|
||||
time.sleep(6)
|
||||
assert sim.lin_active
|
||||
|
||||
send_compare(s, b'ATPC\r', b"OK\r\r>") # STOP KEEPALIVE
|
||||
assert sim.lin_active
|
||||
time.sleep(6)
|
||||
assert not sim.lin_active
|
||||
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
#////////////
|
||||
def test_elm_protocol_autodetect_ISO15765():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, lin=False, silent=True)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
|
||||
send_compare(s, b'ATS0\r', b"OK\r\r>")
|
||||
|
||||
sim.can_mode_11b()
|
||||
send_compare(s, b'ATSP0\r', b"OK\r\r>")
|
||||
send_compare(s, b'010D\r', b"SEARCHING...\r7E803410D53\r\r>", timeout=10)
|
||||
send_compare(s, b'ATDPN\r', b"A6\r\r>")
|
||||
|
||||
sim.can_mode_29b()
|
||||
send_compare(s, b'ATSP0\r', b"OK\r\r>")
|
||||
send_compare(s, b'010D\r', b"SEARCHING...\r18DAF11003410D53\r\r>", timeout=10)
|
||||
send_compare(s, b'ATDPN\r', b"A7\r\r>")
|
||||
|
||||
sim.change_can_baud(250)
|
||||
|
||||
sim.can_mode_11b()
|
||||
send_compare(s, b'ATSP0\r', b"OK\r\r>")
|
||||
send_compare(s, b'010D\r', b"SEARCHING...\r7E803410D53\r\r>", timeout=10)
|
||||
send_compare(s, b'ATDPN\r', b"A8\r\r>")
|
||||
|
||||
sim.can_mode_29b()
|
||||
send_compare(s, b'ATSP0\r', b"OK\r\r>")
|
||||
send_compare(s, b'010D\r', b"SEARCHING...\r18DAF11003410D53\r\r>", timeout=10)
|
||||
send_compare(s, b'ATDPN\r', b"A9\r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_basic_send_can():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, lin=False, silent=True)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATSP6\r', b"ATSP6\rOK\r\r>") # Set Proto
|
||||
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'0100\r', b"41 00 FF FF FF FE \r\r>")
|
||||
send_compare(s, b'010D\r', b"41 0D 53 \r\r>")
|
||||
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces Off
|
||||
send_compare(s, b'0100\r', b"4100FFFFFFFE\r\r>")
|
||||
send_compare(s, b'010D\r', b"410D53\r\r>")
|
||||
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Spaces Off Headers On
|
||||
send_compare(s, b'0100\r', b"7E8064100FFFFFFFE\r\r>")
|
||||
send_compare(s, b'010D\r', b"7E803410D53\r\r>")
|
||||
|
||||
send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces On Headers On
|
||||
send_compare(s, b'0100\r', b"7E8 06 41 00 FF FF FF FE \r\r>")
|
||||
send_compare(s, b'010D\r', b"7E8 03 41 0D 53 \r\r>")
|
||||
|
||||
send_compare(s, b'1F00\r', b"NO DATA\r\r>") # Unhandled msg, no response.
|
||||
|
||||
# Repeat last check to see if it still works after NO DATA was received
|
||||
send_compare(s, b'0100\r', b"7E8 06 41 00 FF FF FF FE \r\r>")
|
||||
send_compare(s, b'010D\r', b"7E8 03 41 0D 53 \r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_send_can_multimsg():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, lin=False)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
|
||||
|
||||
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
|
||||
sim.can_add_extra_noise(b'\x03\x41\x0D\xFA', addr=0x7E9) # Inject message into the stream
|
||||
send_compare(s, b'010D\r',
|
||||
b"7E8 03 41 0D 53 \r"
|
||||
b"7E9 03 41 0D FA \r\r>") # Check it was ignored.
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_can_check_mode_pid():
|
||||
"""The ability to correctly filter out messages with the wrong PID is not
|
||||
implemented correctly in the reference device."""
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, lin=False)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'ATH0\r', b'OK\r\r>') # Headers OFF
|
||||
|
||||
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
|
||||
sim.can_add_extra_noise(b'\x03\x41\x0E\xFA') # Inject message into the stream
|
||||
send_compare(s, b'010D\r', b"410D53\r\r>") # Check it was ignored.
|
||||
send_compare(s, b'0100\r', b"4100FFFFFFFE\r\r>") # Check it was ignored again.
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_send_can_multiline_msg():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, lin=False)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATSP6\r', b"ATSP6\rOK\r\r>") # Set Proto
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
|
||||
send_compare(s, b'0902\r', # headers OFF, Spaces ON
|
||||
b"014 \r"
|
||||
b"0: 49 02 01 31 44 34 \r"
|
||||
b"1: 47 50 30 30 52 35 35 \r"
|
||||
b"2: 42 31 32 33 34 35 36 \r\r>")
|
||||
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'0902\r', # Headers OFF, Spaces OFF
|
||||
b"014\r"
|
||||
b"0:490201314434\r"
|
||||
b"1:47503030523535\r"
|
||||
b"2:42313233343536\r\r>")
|
||||
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
|
||||
send_compare(s, b'0902\r', # Headers ON, Spaces OFF
|
||||
b"7E81014490201314434\r"
|
||||
b"7E82147503030523535\r"
|
||||
b"7E82242313233343536\r\r>")
|
||||
|
||||
send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces ON
|
||||
send_compare(s, b'0902\r', # Headers ON, Spaces ON
|
||||
b"7E8 10 14 49 02 01 31 44 34 \r"
|
||||
b"7E8 21 47 50 30 30 52 35 35 \r"
|
||||
b"7E8 22 42 31 32 33 34 35 36 \r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_send_can_multiline_msg_throughput():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, lin=False, silent=True)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATSP6\r', b"ATSP6\rOK\r\r>") # Set Proto
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
|
||||
|
||||
rows = 584
|
||||
send_compare(s, b'09ff\r', # headers ON, Spaces OFF
|
||||
("7E8" + "1" + hex((rows * 7) + 6)[2:].upper().zfill(3) + "49FF01" + "AA0000\r" +
|
||||
"".join(
|
||||
("7E82" + hex((num + 1) % 0x10)[2:].upper() + ("AA" * 5) +
|
||||
hex(num + 1)[2:].upper().zfill(4) + "\r" for num in range(rows))
|
||||
) + "\r>").encode(),
|
||||
timeout=10
|
||||
)
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_interrupted_obd_cmd_resets_state():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, lin=False, silent=True)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
s.send(b"09fd\r")
|
||||
ready = select.select([s], [], [], 4)
|
||||
assert ready[0], "Socket did not receive data within the timeout duration."
|
||||
s.send(b"ATI\r")
|
||||
|
||||
assert b"236\r0:49FD01AAAAAA\r" in s.recv(10000)
|
||||
|
||||
#Will likely have to be improved to scan for STOPPED if the FW gets more responsive.
|
||||
ready = select.select([s], [], [], 4)
|
||||
assert ready[0], "Socket did not receive data within the timeout duration."
|
||||
|
||||
assert b"STOPPED" in s.recv(10000)
|
||||
|
||||
sim.set_enable(False)
|
||||
send_compare(s, b'09fd\r', b"NO DATA\r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_can_baud():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
sim = elm_car_simulator.ELMCarSimulator(serial, lin=False)
|
||||
sim.start()
|
||||
|
||||
try:
|
||||
sync_reset(s)
|
||||
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
|
||||
|
||||
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
|
||||
send_compare(s, b'0100\r', b"7E8064100FFFFFFFE\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP8\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/250)
|
||||
send_compare(s, b'0100\r', b"CAN ERROR\r\r>")
|
||||
|
||||
sim.change_can_baud(250)
|
||||
|
||||
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
|
||||
send_compare(s, b'0100\r', b"CAN ERROR\r\r>")
|
||||
|
||||
send_compare(s, b'ATSP8\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/250)
|
||||
send_compare(s, b'0100\r', b"7E8064100FFFFFFFE\r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
s.close()
|
||||
|
||||
def test_elm_panda_safety_mode_ISO15765():
|
||||
s = elm_connect()
|
||||
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
|
||||
p_car = Panda(serial) # Configure this so the messages will send
|
||||
p_car.set_can_speed_kbps(0, 500)
|
||||
p_car.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
|
||||
p_elm = Panda("WIFI")
|
||||
p_elm.set_safety_mode(Panda.SAFETY_ELM327)
|
||||
|
||||
#sim = elm_car_simulator.ELMCarSimulator(serial, lin=False)
|
||||
#sim.start()
|
||||
|
||||
def did_send(p, addr, dat, bus):
|
||||
p.can_send(addr, dat, bus)
|
||||
t = time.time()
|
||||
while time.time() - t < 0.5:
|
||||
msg = p.can_recv()
|
||||
for addrin, _, datin, busin in msg:
|
||||
if (0x80 | bus) == busin and addr == addrin and datin == dat:
|
||||
return True
|
||||
time.sleep(0.01)
|
||||
return False
|
||||
|
||||
try:
|
||||
sync_reset(s) # Reset elm (which requests the ELM327 safety mode)
|
||||
|
||||
#29 bit
|
||||
assert not did_send(p_elm, 0x18DB33F1, b'\x02\x01\x00\x00\x00\x00\x00\x00', 1) # wrong canid
|
||||
assert not did_send(p_elm, 0x18DB33F1, b'\x02\x01\x00', 0) # wrong length
|
||||
assert not did_send(p_elm, 0x10000000, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # bad addr
|
||||
assert not did_send(p_elm, 0x18DAF133, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # bad addr (phy addr)
|
||||
assert not did_send(p_elm, 0x18DAF000, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # bad addr
|
||||
assert not did_send(p_elm, 0x18DAF1F3, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # bad addr! (phys rsp to elm)
|
||||
|
||||
assert did_send(p_elm, 0x18DB33F1, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # good! (obd func req)
|
||||
assert did_send(p_elm, 0x18DA10F1, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # good! (phys response)
|
||||
|
||||
#11 bit
|
||||
assert not did_send(p_elm, 0X7DF, b'\x02\x01\x00\x00\x00\x00\x00\x00', 1) # wrong canid
|
||||
assert not did_send(p_elm, 0X7DF, b'\x02\x01\x00', 0) # wrong length
|
||||
assert not did_send(p_elm, 0xAA, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # bad addr
|
||||
assert not did_send(p_elm, 0x7DA, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # bad addr (phy addr)
|
||||
assert not did_send(p_elm, 0x7E8, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # bad addr (sending 'response')
|
||||
|
||||
assert did_send(p_elm, 0x7DF, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # good! (obd func req)
|
||||
assert did_send(p_elm, 0x7E1, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) # good! (phys response)
|
||||
|
||||
finally:
|
||||
s.close()
|
Loading…
Reference in New Issue