open source driving agent
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

237 lines
6.3 KiB

#pragma once
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the PANDA_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// PANDA_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef PANDA_EXPORTS
#define PANDA_API __declspec(dllexport)
#else
#define PANDA_API
#endif
#include <vector>
#include <string>
#include <unordered_map>
#include <memory>
#include <iostream>
#include <chrono>
#include <windows.h>
#include <winusb.h>
#if defined(UNICODE)
#define _tcout std::wcout
#define tstring std::wstring
#else
#define _tcout std::cout
#define tstring std::string
#endif
#define LIN_MSG_MAX_LEN 10
#define CAN_RX_QUEUE_LEN 10000
#define CAN_RX_MSG_LEN 1000
//template class __declspec(dllexport) std::basic_string<char>;
namespace panda {
typedef enum _PANDA_SAFETY_MODE : uint16_t {
SAFETY_SILENT = 0,
SAFETY_HONDA = 1,
SAFETY_ALLOUTPUT = 17,
} PANDA_SAFETY_MODE;
typedef enum _PANDA_SERIAL_PORT : uint8_t {
SERIAL_DEBUG = 0,
SERIAL_ESP = 1,
SERIAL_LIN1 = 2,
SERIAL_LIN2 = 3,
} PANDA_SERIAL_PORT;
typedef enum _PANDA_SERIAL_PORT_PARITY : uint8_t {
PANDA_PARITY_OFF = 0,
PANDA_PARITY_EVEN = 1,
PANDA_PARITY_ODD = 2,
} PANDA_SERIAL_PORT_PARITY;
typedef enum _PANDA_CAN_PORT : uint8_t {
PANDA_CAN1 = 0,
PANDA_CAN2 = 1,
PANDA_CAN3 = 2,
PANDA_CAN_UNK = 0xFF,
} PANDA_CAN_PORT;
typedef enum _PANDA_CAN_PORT_CLEAR : uint16_t {
PANDA_CAN1_TX = 0,
PANDA_CAN2_TX = 1,
PANDA_CAN3_TX = 2,
PANDA_CAN_RX = 0xFFFF,
} PANDA_CAN_PORT_CLEAR;
typedef enum _PANDA_GMLAN_HOST_PORT : uint8_t {
PANDA_GMLAN_CLEAR = 0,
PANDA_GMLAN_CAN2 = 1,
PANDA_GMLAN_CAN3 = 2,
} PANDA_GMLAN_HOST_PORT;
#pragma pack(1)
typedef struct _PANDA_HEALTH {
uint32_t voltage;
uint32_t current;
uint8_t started;
uint8_t controls_allowed;
uint8_t gas_interceptor_detected;
uint8_t started_signal_detected;
uint8_t started_alt;
} PANDA_HEALTH, *PPANDA_HEALTH;
typedef struct _PANDA_CAN_MSG {
uint32_t addr;
unsigned long long recv_time; //In microseconds since device initialization
std::chrono::time_point<std::chrono::steady_clock> recv_time_point;
uint8_t dat[8];
uint8_t len;
PANDA_CAN_PORT bus;
bool is_receipt;
bool addr_29b;
} PANDA_CAN_MSG;
//Copied from https://stackoverflow.com/a/31488113
class Timer
{
using clock = std::chrono::steady_clock;
using time_point_type = std::chrono::time_point < clock, std::chrono::microseconds >;
public:
Timer() {
start = std::chrono::time_point_cast<std::chrono::microseconds>(clock::now());
}
// gets the time elapsed from construction.
unsigned long long /*microseconds*/ Timer::getTimePassedUS() {
// get the new time
auto end = std::chrono::time_point_cast<std::chrono::microseconds>(clock::now());
// return the difference of the times
return (end - start).count();
}
// gets the time elapsed from construction.
unsigned long long /*milliseconds*/ Timer::getTimePassedMS() {
// get the new time
auto end = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
// return the difference of the times
auto startms = std::chrono::time_point_cast<std::chrono::milliseconds>(start);
return (end - startms).count();
}
private:
time_point_type start;
};
// This class is exported from the panda.dll
class PANDA_API Panda {
public:
static std::vector<std::string> listAvailablePandas();
static std::unique_ptr<Panda> openPanda(std::string sn);
~Panda();
std::string get_usb_sn();
bool set_alt_setting(UCHAR alt_setting);
UCHAR get_current_alt_setting();
bool Panda::set_raw_io(bool val);
PANDA_HEALTH get_health();
bool enter_bootloader();
std::string get_version();
std::string get_serial();
std::string get_secret();
bool set_usb_power(bool on);
bool set_esp_power(bool on);
bool esp_reset(uint16_t bootmode);
bool set_safety_mode(PANDA_SAFETY_MODE mode);
bool set_can_forwarding(PANDA_CAN_PORT from_bus, PANDA_CAN_PORT to_bus);
bool set_gmlan(PANDA_GMLAN_HOST_PORT bus);
bool set_can_loopback(bool enable);
bool set_can_speed_cbps(PANDA_CAN_PORT bus, uint16_t speed);
bool set_can_speed_kbps(PANDA_CAN_PORT bus, uint16_t speed);
bool set_uart_baud(PANDA_SERIAL_PORT uart, uint32_t rate);
bool set_uart_parity(PANDA_SERIAL_PORT uart, PANDA_SERIAL_PORT_PARITY parity);
bool can_send_many(const std::vector<PANDA_CAN_MSG>& can_msgs);
bool can_send(uint32_t addr, bool addr_29b, const uint8_t *dat, uint8_t len, PANDA_CAN_PORT bus);
std::vector<PANDA_CAN_MSG> can_recv();
bool can_rx_q_push(HANDLE kill_event, DWORD timeoutms = INFINITE);
void can_rx_q_pop(PANDA_CAN_MSG msg_out[], int &count);
bool can_clear(PANDA_CAN_PORT_CLEAR bus);
std::string serial_read(PANDA_SERIAL_PORT port_number);
int serial_write(PANDA_SERIAL_PORT port_number, const void* buff, uint16_t len);
bool serial_clear(PANDA_SERIAL_PORT port_number);
private:
Panda(
WINUSB_INTERFACE_HANDLE WinusbHandle,
HANDLE DeviceHandle,
tstring devPath_,
std::string sn_
);
int control_transfer(
uint8_t bmRequestType,
uint8_t bRequest,
uint16_t wValue,
uint16_t wIndex,
void * data,
uint16_t wLength,
unsigned int timeout
);
int bulk_write(
UCHAR endpoint,
const void * buff,
ULONG length,
PULONG transferred,
ULONG timeout
);
int Panda::bulk_read(
UCHAR endpoint,
void * buff,
ULONG buff_size,
PULONG transferred,
ULONG timeout
);
#pragma pack(1)
typedef struct _PANDA_CAN_MSG_INTERNAL {
uint32_t rir;
uint32_t f2;
uint8_t dat[8];
} PANDA_CAN_MSG_INTERNAL;
typedef struct _CAN_RX_PIPE_READ {
unsigned char data[sizeof(PANDA_CAN_MSG_INTERNAL) * CAN_RX_MSG_LEN];
unsigned long count;
OVERLAPPED overlapped;
HANDLE complete;
DWORD error;
} CAN_RX_PIPE_READ;
PANDA_CAN_MSG parse_can_recv(PANDA_CAN_MSG_INTERNAL *in_msg_raw);
WINUSB_INTERFACE_HANDLE usbh;
HANDLE devh;
tstring devPath;
std::string sn;
bool loopback;
Timer runningTime;
CAN_RX_PIPE_READ can_rx_q[CAN_RX_QUEUE_LEN];
unsigned long w_ptr = 0;
unsigned long r_ptr = 0;
};
}