Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Committer:
Just4pLeisure
Date:
Sat Apr 23 18:31:40 2016 +0000
Revision:
6:2fbcbebed28c
Parent:
5:1775b4b13232
Version 1.6 Faster T7 P-BUS FLASHing algorithm, longer T8 erase timeout fixed BDM register display function

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Just4pLeisure 4:682d96ff6d79 1 /*******************************************************************************
Just4pLeisure 4:682d96ff6d79 2
Just4pLeisure 4:682d96ff6d79 3 trionic8.cpp - CAN Bus functions for Just4Trionic by Just4pLeisure
Just4pLeisure 4:682d96ff6d79 4 (c) 2011, 2012 by Sophie Dexter
Just4pLeisure 4:682d96ff6d79 5
Just4pLeisure 4:682d96ff6d79 6 This C++ module provides functions for reading and writing the FLASH chips and
Just4pLeisure 4:682d96ff6d79 7 SRAM in Trionic8 ECUs. (Writing the adaption data back to SRAM not done yet).
Just4pLeisure 4:682d96ff6d79 8
Just4pLeisure 4:682d96ff6d79 9 Some functions need an additional 'bootloader' program to be sent to the T8 ECU
Just4pLeisure 4:682d96ff6d79 10 before they can be used. These functions are: Identifying the T5 ECU type and
Just4pLeisure 4:682d96ff6d79 11 FLASH chips, dumping the FLASH chips, erasing the FLASH chips, writing to the
Just4pLeisure 4:682d96ff6d79 12 FLASH chips and calculating the FLASH chips' checksum.
Just4pLeisure 4:682d96ff6d79 13
Just4pLeisure 4:682d96ff6d79 14 ********************************************************************************
Just4pLeisure 4:682d96ff6d79 15
Just4pLeisure 4:682d96ff6d79 16 WARNING: Use at your own risk, sadly this software comes with no guarantees.
Just4pLeisure 4:682d96ff6d79 17 This software is provided 'free' and in good faith, but the author does not
Just4pLeisure 4:682d96ff6d79 18 accept liability for any damage arising from its use.
Just4pLeisure 4:682d96ff6d79 19
Just4pLeisure 4:682d96ff6d79 20 *******************************************************************************/
Just4pLeisure 4:682d96ff6d79 21
Just4pLeisure 4:682d96ff6d79 22 #include "t8can.h"
Just4pLeisure 4:682d96ff6d79 23
Just4pLeisure 4:682d96ff6d79 24 // constants
Just4pLeisure 4:682d96ff6d79 25 #define CMD_BUF_LENGTH 32 ///< command buffer size
Just4pLeisure 4:682d96ff6d79 26
Just4pLeisure 4:682d96ff6d79 27 // static variables
Just4pLeisure 4:682d96ff6d79 28 static char cmd_buffer[CMD_BUF_LENGTH]; ///< command string buffer
Just4pLeisure 4:682d96ff6d79 29
Just4pLeisure 4:682d96ff6d79 30 //static uint32_t cmd_addr; ///< address (optional)
Just4pLeisure 4:682d96ff6d79 31 //static uint32_t cmd_value; ///< value (optional)
Just4pLeisure 4:682d96ff6d79 32 //static uint32_t cmd_result; ///< result
Just4pLeisure 4:682d96ff6d79 33
Just4pLeisure 4:682d96ff6d79 34 //static uint32_t flash_start = 0;
Just4pLeisure 4:682d96ff6d79 35
Just4pLeisure 4:682d96ff6d79 36 // private functions
Just4pLeisure 4:682d96ff6d79 37 uint8_t execute_t8_cmd();
Just4pLeisure 4:682d96ff6d79 38 void t8_can_show_help();
Just4pLeisure 4:682d96ff6d79 39 void t8_can_show_full_help();
Just4pLeisure 4:682d96ff6d79 40
Just4pLeisure 4:682d96ff6d79 41 void t8_can()
Just4pLeisure 4:682d96ff6d79 42 {
Just4pLeisure 4:682d96ff6d79 43 // Start the CAN bus system
Just4pLeisure 4:682d96ff6d79 44 // Note that at the moment this is only for T8 ECUs at 500 kbits
Just4pLeisure 4:682d96ff6d79 45 t8_can_show_help();
Just4pLeisure 4:682d96ff6d79 46
Just4pLeisure 4:682d96ff6d79 47 char data[8];
Just4pLeisure 4:682d96ff6d79 48 printf("Trying to listen to CAN P-Bus (500 kBit/s)...\r\n");
Just4pLeisure 4:682d96ff6d79 49 can_configure(2, 500000, 1);
Just4pLeisure 4:682d96ff6d79 50 if (can_wait_timeout(T8ANYMSG, data, 8, T8MESSAGETIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 51 printf("Connected to Saab P-Bus\r\n");
Just4pLeisure 4:682d96ff6d79 52 printf("Switching to P-Bus active mode\r\n");
Just4pLeisure 4:682d96ff6d79 53 can_configure(2, 500000, 0);
Just4pLeisure 4:682d96ff6d79 54 } else {
Just4pLeisure 4:682d96ff6d79 55 printf("I did not receive any P-Bus messages\r\n");
Just4pLeisure 4:682d96ff6d79 56 printf("Switching to P-Bus active mode\r\n");
Just4pLeisure 4:682d96ff6d79 57 can_configure(2, 500000, 0);
Just4pLeisure 4:682d96ff6d79 58 if (can_wait_timeout(T8ANYMSG, data, 8, T8CONNECTTIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 59 printf("Connected to Saab P-Bus\r\n");
Just4pLeisure 4:682d96ff6d79 60 //can_active();
Just4pLeisure 4:682d96ff6d79 61 } else {
Just4pLeisure 4:682d96ff6d79 62 printf("FAILED to connect!\r\n");
Just4pLeisure 4:682d96ff6d79 63 led4 = 1;
Just4pLeisure 4:682d96ff6d79 64 }
Just4pLeisure 4:682d96ff6d79 65 }
Just4pLeisure 4:682d96ff6d79 66
Just4pLeisure 5:1775b4b13232 67 can_reset_filters();
Just4pLeisure 5:1775b4b13232 68 can_add_filter(2, 0x645); //645h - CIM
Just4pLeisure 5:1775b4b13232 69 can_add_filter(2, 0x7E0); //7E0h -
Just4pLeisure 5:1775b4b13232 70 can_add_filter(2, 0x7E8); //7E8h -
Just4pLeisure 5:1775b4b13232 71 can_add_filter(2, 0x311); //311h -
Just4pLeisure 5:1775b4b13232 72 can_add_filter(2, 0x5E8); //5E8h -
Just4pLeisure 5:1775b4b13232 73 //can_add_filter(2, 0x101); //101h -
Just4pLeisure 5:1775b4b13232 74
Just4pLeisure 5:1775b4b13232 75
Just4pLeisure 4:682d96ff6d79 76 // main loop
Just4pLeisure 4:682d96ff6d79 77 *cmd_buffer = '\0';
Just4pLeisure 4:682d96ff6d79 78 char ret;
Just4pLeisure 4:682d96ff6d79 79 char rx_char;
Just4pLeisure 4:682d96ff6d79 80 while (true) {
Just4pLeisure 4:682d96ff6d79 81 // read chars from USB
Just4pLeisure 4:682d96ff6d79 82 // send received messages to the pc over USB connection
Just4pLeisure 4:682d96ff6d79 83 // This function displays any CAN messages that are 'missed' by the other functions
Just4pLeisure 4:682d96ff6d79 84 // Can messages might be 'missed' because they are received after a 'timeout' period
Just4pLeisure 4:682d96ff6d79 85 // or because they weren't expected, e.g. if the T5 ECU resets for some reason
Just4pLeisure 4:682d96ff6d79 86 // t7_show_can_message();
Just4pLeisure 4:682d96ff6d79 87 silent_can_message();
Just4pLeisure 4:682d96ff6d79 88 if (pc.readable()) {
Just4pLeisure 4:682d96ff6d79 89 // turn Error LED off for next command
Just4pLeisure 4:682d96ff6d79 90 led4 = 0;
Just4pLeisure 4:682d96ff6d79 91 rx_char = pc.getc();
Just4pLeisure 4:682d96ff6d79 92 switch (rx_char) {
Just4pLeisure 4:682d96ff6d79 93 // 'ESC' key to go back to mbed Just4Trionic 'home' menu
Just4pLeisure 4:682d96ff6d79 94 case '\e':
Just4pLeisure 4:682d96ff6d79 95 can_close();
Just4pLeisure 4:682d96ff6d79 96 return;
Just4pLeisure 4:682d96ff6d79 97 // end-of-command reached
Just4pLeisure 4:682d96ff6d79 98 case TERM_OK :
Just4pLeisure 4:682d96ff6d79 99 // execute command and return flag via USB
Just4pLeisure 4:682d96ff6d79 100 timer.reset();
Just4pLeisure 4:682d96ff6d79 101 timer.start();
Just4pLeisure 4:682d96ff6d79 102 ret = execute_t8_cmd();
Just4pLeisure 4:682d96ff6d79 103 pc.putc(ret);
Just4pLeisure 4:682d96ff6d79 104 printf("Completed in %.3f seconds.\r\n", timer.read());
Just4pLeisure 4:682d96ff6d79 105 // reset command buffer
Just4pLeisure 4:682d96ff6d79 106 *cmd_buffer = '\0';
Just4pLeisure 4:682d96ff6d79 107 // light up LED
Just4pLeisure 4:682d96ff6d79 108 // ret == TERM_OK ? led_on(LED_ACT) : led_on(LED_ERR);
Just4pLeisure 4:682d96ff6d79 109 ret == TERM_OK ? led3 = 1 : led4 = 1;
Just4pLeisure 4:682d96ff6d79 110 break;
Just4pLeisure 4:682d96ff6d79 111 // another command char
Just4pLeisure 4:682d96ff6d79 112 default:
Just4pLeisure 4:682d96ff6d79 113 // store in buffer if space permits
Just4pLeisure 4:682d96ff6d79 114 if (StrLen(cmd_buffer) < CMD_BUF_LENGTH - 1) {
Just4pLeisure 4:682d96ff6d79 115 StrAddc(cmd_buffer, rx_char);
Just4pLeisure 4:682d96ff6d79 116 }
Just4pLeisure 4:682d96ff6d79 117 break;
Just4pLeisure 4:682d96ff6d79 118 }
Just4pLeisure 4:682d96ff6d79 119 }
Just4pLeisure 4:682d96ff6d79 120 }
Just4pLeisure 4:682d96ff6d79 121 }
Just4pLeisure 4:682d96ff6d79 122
Just4pLeisure 4:682d96ff6d79 123 //-----------------------------------------------------------------------------
Just4pLeisure 4:682d96ff6d79 124 /**
Just4pLeisure 4:682d96ff6d79 125 Executes a command and returns result flag (does not transmit the flag
Just4pLeisure 4:682d96ff6d79 126 itself).
Just4pLeisure 4:682d96ff6d79 127
Just4pLeisure 4:682d96ff6d79 128 @return command flag (success / failure)
Just4pLeisure 4:682d96ff6d79 129 */
Just4pLeisure 4:682d96ff6d79 130 uint8_t execute_t8_cmd()
Just4pLeisure 4:682d96ff6d79 131 {
Just4pLeisure 4:682d96ff6d79 132
Just4pLeisure 4:682d96ff6d79 133 char data[8];
Just4pLeisure 4:682d96ff6d79 134 // uint8_t cmd_length = strlen(cmd_buffer);
Just4pLeisure 4:682d96ff6d79 135 // command groups
Just4pLeisure 4:682d96ff6d79 136 switch (*cmd_buffer) {
Just4pLeisure 4:682d96ff6d79 137 // CHECK_ARGLENGTH(0);
Just4pLeisure 4:682d96ff6d79 138 // Get the Symbol Table
Just4pLeisure 4:682d96ff6d79 139 case 'i' :
Just4pLeisure 4:682d96ff6d79 140 if (t8_initialise()) {
Just4pLeisure 4:682d96ff6d79 141 printf("Trionic 8 Connection OK\r\n");
Just4pLeisure 4:682d96ff6d79 142 return TERM_OK;
Just4pLeisure 4:682d96ff6d79 143 } else {
Just4pLeisure 4:682d96ff6d79 144 printf("Trionic 8 Connection Failed\r\n");
Just4pLeisure 4:682d96ff6d79 145 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 146 }
Just4pLeisure 4:682d96ff6d79 147 // return t7_initialise()
Just4pLeisure 4:682d96ff6d79 148 // ? TERM_OK : TERM_ERR;
Just4pLeisure 4:682d96ff6d79 149 case 'a' :
Just4pLeisure 4:682d96ff6d79 150 case 'A' :
Just4pLeisure 5:1775b4b13232 151 if (t8_authenticate(T8REQID, T8RESPID, 0x01)) {
Just4pLeisure 4:682d96ff6d79 152 printf("Security Key Accepted\r\n");
Just4pLeisure 4:682d96ff6d79 153 return TERM_OK;
Just4pLeisure 4:682d96ff6d79 154 } else {
Just4pLeisure 4:682d96ff6d79 155 printf("Security Key Failed\r\n");
Just4pLeisure 4:682d96ff6d79 156 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 157 }
Just4pLeisure 4:682d96ff6d79 158 // return t7_authenticate()
Just4pLeisure 4:682d96ff6d79 159 // ? TERM_OK : TERM_ERR;
Just4pLeisure 4:682d96ff6d79 160
Just4pLeisure 4:682d96ff6d79 161 // DUMP the T8 ECU BIN file stored in the FLASH chips
Just4pLeisure 4:682d96ff6d79 162 case 'D':
Just4pLeisure 4:682d96ff6d79 163 case 'd':
Just4pLeisure 4:682d96ff6d79 164 return t8_dump()
Just4pLeisure 4:682d96ff6d79 165 ? TERM_OK : TERM_ERR;
Just4pLeisure 4:682d96ff6d79 166 // Send a FLASH update file to the T8 ECU
Just4pLeisure 4:682d96ff6d79 167 case 'F':
Just4pLeisure 4:682d96ff6d79 168 case 'f':
Just4pLeisure 4:682d96ff6d79 169 return t8_flash()
Just4pLeisure 4:682d96ff6d79 170 ? TERM_OK : TERM_ERR;
Just4pLeisure 5:1775b4b13232 171 // Erase the FLASH chips
Just4pLeisure 5:1775b4b13232 172 case 'r':
Just4pLeisure 5:1775b4b13232 173 case 'R':
Just4pLeisure 5:1775b4b13232 174 return t8_recover()
Just4pLeisure 5:1775b4b13232 175 ? TERM_OK : TERM_ERR;
Just4pLeisure 4:682d96ff6d79 176 // Try to connect to CAN I-BUS
Just4pLeisure 4:682d96ff6d79 177 case 'I' :
Just4pLeisure 4:682d96ff6d79 178 printf("Trying to open CAN I-Bus (47619 Bit/s)...\r\n");
Just4pLeisure 4:682d96ff6d79 179 can_close();
Just4pLeisure 4:682d96ff6d79 180 //can_monitor();
Just4pLeisure 4:682d96ff6d79 181 can_set_speed(47619);
Just4pLeisure 4:682d96ff6d79 182 can_open();
Just4pLeisure 4:682d96ff6d79 183 if (can_wait_timeout(T8ANYMSG, data, 8, T8CONNECTTIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 184 printf("Connected to Saab I-Bus\r\n");
Just4pLeisure 4:682d96ff6d79 185 //can_active();
Just4pLeisure 4:682d96ff6d79 186 return TERM_OK;
Just4pLeisure 4:682d96ff6d79 187 } else {
Just4pLeisure 4:682d96ff6d79 188 printf("I did not receive any I-Bus messages\r\n");
Just4pLeisure 4:682d96ff6d79 189 printf("FAILED to connect!\r\n");
Just4pLeisure 4:682d96ff6d79 190 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 191 }
Just4pLeisure 4:682d96ff6d79 192 // Try to connect to CAN P-BUS
Just4pLeisure 4:682d96ff6d79 193 case 'P' :
Just4pLeisure 4:682d96ff6d79 194 printf("Trying to open CAN P-Bus (500 kBit/s)...\r\n");
Just4pLeisure 4:682d96ff6d79 195 can_close();
Just4pLeisure 4:682d96ff6d79 196 //can_monitor();
Just4pLeisure 4:682d96ff6d79 197 can_set_speed(500000);
Just4pLeisure 4:682d96ff6d79 198 can_open();
Just4pLeisure 4:682d96ff6d79 199 if (can_wait_timeout(T8ANYMSG, data, 8, T8CONNECTTIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 200 printf("Connected to Saab P-Bus\r\n");
Just4pLeisure 4:682d96ff6d79 201 //can_active();
Just4pLeisure 4:682d96ff6d79 202 return TERM_OK;
Just4pLeisure 4:682d96ff6d79 203 } else {
Just4pLeisure 4:682d96ff6d79 204 printf("I did not receive any P-Bus messages\r\n");
Just4pLeisure 4:682d96ff6d79 205 printf("FAILED to connect!\r\n");
Just4pLeisure 4:682d96ff6d79 206 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 207 }
Just4pLeisure 4:682d96ff6d79 208 // Show the VIN code
Just4pLeisure 4:682d96ff6d79 209 case 'v':
Just4pLeisure 4:682d96ff6d79 210 return t8_show_VIN()
Just4pLeisure 4:682d96ff6d79 211 ? TERM_OK : TERM_ERR;
Just4pLeisure 4:682d96ff6d79 212 case 'V':
Just4pLeisure 4:682d96ff6d79 213 return t8_write_VIN()
Just4pLeisure 4:682d96ff6d79 214 ? TERM_OK : TERM_ERR;
Just4pLeisure 4:682d96ff6d79 215 // Print help
Just4pLeisure 4:682d96ff6d79 216 case 'h':
Just4pLeisure 4:682d96ff6d79 217 t8_can_show_help();
Just4pLeisure 4:682d96ff6d79 218 return TERM_OK;
Just4pLeisure 4:682d96ff6d79 219 case 'H':
Just4pLeisure 4:682d96ff6d79 220 t8_can_show_full_help();
Just4pLeisure 4:682d96ff6d79 221 return TERM_OK;
Just4pLeisure 4:682d96ff6d79 222 default:
Just4pLeisure 4:682d96ff6d79 223 t8_can_show_help();
Just4pLeisure 4:682d96ff6d79 224 break;
Just4pLeisure 4:682d96ff6d79 225 }
Just4pLeisure 4:682d96ff6d79 226 // unknown command
Just4pLeisure 4:682d96ff6d79 227 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 228 }
Just4pLeisure 4:682d96ff6d79 229
Just4pLeisure 4:682d96ff6d79 230 //
Just4pLeisure 4:682d96ff6d79 231 // Trionic7ShowHelp
Just4pLeisure 4:682d96ff6d79 232 //
Just4pLeisure 4:682d96ff6d79 233 // Displays a list of things that can be done with the T5 ECU.
Just4pLeisure 4:682d96ff6d79 234 //
Just4pLeisure 4:682d96ff6d79 235 // inputs: none
Just4pLeisure 4:682d96ff6d79 236 // return: none
Just4pLeisure 4:682d96ff6d79 237 //
Just4pLeisure 4:682d96ff6d79 238 void t8_can_show_help()
Just4pLeisure 4:682d96ff6d79 239 {
Just4pLeisure 4:682d96ff6d79 240 printf("Trionic 8 Command Menu\r\n");
Just4pLeisure 4:682d96ff6d79 241 printf("======================\r\n");
Just4pLeisure 4:682d96ff6d79 242 printf("D - DUMP the T8 ECU FLASH to a file 'ORIGINAL.BIN'\r\n");
Just4pLeisure 5:1775b4b13232 243 printf("F - FLASH the update file 'MODIFIED.BIN' to the T8\r\n");
Just4pLeisure 5:1775b4b13232 244 printf("R - Recover your T8 ECU FLASH with 'MODIFIED.BIN' file\r\n");
Just4pLeisure 4:682d96ff6d79 245 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 246 printf("I - Try to open CAN I-Bus (47619 Bit/s)\r\n");
Just4pLeisure 4:682d96ff6d79 247 printf("P - Try to open CAN P-Bus (500 kBit/s)\r\n");
Just4pLeisure 4:682d96ff6d79 248 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 249 printf("'ESC' - Return to Just4Trionic Main Menu\r\n");
Just4pLeisure 4:682d96ff6d79 250 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 251 printf("h - Show this help menu\r\n");
Just4pLeisure 4:682d96ff6d79 252 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 253 return;
Just4pLeisure 4:682d96ff6d79 254 }
Just4pLeisure 4:682d96ff6d79 255 //
Just4pLeisure 4:682d96ff6d79 256 // t7_can_show_full_help
Just4pLeisure 4:682d96ff6d79 257 //
Just4pLeisure 4:682d96ff6d79 258 // Displays a complete list of things that can be done with the T5 ECU.
Just4pLeisure 4:682d96ff6d79 259 //
Just4pLeisure 4:682d96ff6d79 260 // inputs: none
Just4pLeisure 4:682d96ff6d79 261 // return: none
Just4pLeisure 4:682d96ff6d79 262 //
Just4pLeisure 4:682d96ff6d79 263 void t8_can_show_full_help()
Just4pLeisure 4:682d96ff6d79 264 {
Just4pLeisure 4:682d96ff6d79 265 printf("Trionic 8 Command Menu\r\n");
Just4pLeisure 4:682d96ff6d79 266 printf("======================\r\n");
Just4pLeisure 4:682d96ff6d79 267 printf("D - DUMP the T8 ECU FLASH to a file 'ORIGINAL.BIN'\r\n");
Just4pLeisure 5:1775b4b13232 268 printf("F - FLASH the update file 'MODIFIED.BIN' to the T8\r\n");
Just4pLeisure 5:1775b4b13232 269 printf("R - Recover your T8 ECU FLASH with 'MODIFIED.BIN' file\r\n");
Just4pLeisure 4:682d96ff6d79 270 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 271 printf("I - Try to open CAN I-Bus (47619 Bit/s)\r\n");
Just4pLeisure 4:682d96ff6d79 272 printf("P - Try to open CAN P-Bus (500 kBit/s)\r\n");
Just4pLeisure 4:682d96ff6d79 273 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 274 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 275 printf("i - Send initialisation message to T8\r\n");
Just4pLeisure 4:682d96ff6d79 276 printf("a - Send Authentication key to T8\r\n");
Just4pLeisure 4:682d96ff6d79 277 printf("d - Dump T8 Bin file 'ORIGINAL.BIN'\r\n");
Just4pLeisure 4:682d96ff6d79 278 printf("e - Erase the FLASH in the T8 ECU\r\n");
Just4pLeisure 4:682d96ff6d79 279 printf("f - FLASH the file 'MODIFIED.BIN' to the T8 ECU\r\n");
Just4pLeisure 4:682d96ff6d79 280 printf("v - Display the current VIN code stored in the T8 ECU\r\n");
Just4pLeisure 4:682d96ff6d79 281 printf("V - FLASH the file 'MODIFIED.BIN' to the T8 ECU\r\n");
Just4pLeisure 4:682d96ff6d79 282 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 283 printf("'ESC' - Return to Just4Trionic Main Menu\r\n");
Just4pLeisure 4:682d96ff6d79 284 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 285 printf("H - Show this help menu\r\n");
Just4pLeisure 4:682d96ff6d79 286 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 287 return;
Just4pLeisure 4:682d96ff6d79 288 }
Just4pLeisure 4:682d96ff6d79 289
Just4pLeisure 4:682d96ff6d79 290