Blynk library for embedded hardware. Works with Arduino, ESP8266, Raspberry Pi, Intel Edison/Galileo, LinkIt ONE, Particle Core/Photon, Energia, ARM mbed, etc. http://www.blynk.cc/

Dependents:   Blynk_RBL_BLE_Nano Blynk_MicroBit Blynk_Serial Blynk_RBL_BLE_Nano

Committer:
Volodymyr Shymanskyy
Date:
Mon Nov 27 23:01:23 2017 +0200
Revision:
16:6d9bf99b263c
Parent:
15:975b60f7a8ff
Child:
18:c328c1a97f90
Update version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vshymanskyy 0:58b20b438383 1 /**
vshymanskyy 0:58b20b438383 2 * @file BlynkDebug.cpp
vshymanskyy 0:58b20b438383 3 * @author Volodymyr Shymanskyy
vshymanskyy 0:58b20b438383 4 * @license This project is released under the MIT License (MIT)
vshymanskyy 0:58b20b438383 5 * @copyright Copyright (c) 2015 Volodymyr Shymanskyy
vshymanskyy 0:58b20b438383 6 * @date Jan 2015
vshymanskyy 0:58b20b438383 7 * @brief Debug utilities for Arduino
vshymanskyy 0:58b20b438383 8 */
Volodymyr Shymanskyy 9:7369ec77a3ea 9 #include <Blynk/BlynkDebug.h>
vshymanskyy 0:58b20b438383 10
Volodymyr Shymanskyy 15:975b60f7a8ff 11 #if defined(ARDUINO) && defined(__AVR__) && defined(BLYNK_USE_AVR_WDT)
Volodymyr Shymanskyy 9:7369ec77a3ea 12
Volodymyr Shymanskyy 9:7369ec77a3ea 13 #include <Arduino.h>
Volodymyr Shymanskyy 9:7369ec77a3ea 14 #include <avr/wdt.h>
Volodymyr Shymanskyy 9:7369ec77a3ea 15
Volodymyr Shymanskyy 16:6d9bf99b263c 16 BLYNK_CONSTRUCTOR
Volodymyr Shymanskyy 15:975b60f7a8ff 17 static void BlynkSystemInit()
Volodymyr Shymanskyy 9:7369ec77a3ea 18 {
Volodymyr Shymanskyy 9:7369ec77a3ea 19 MCUSR = 0;
Volodymyr Shymanskyy 9:7369ec77a3ea 20 wdt_disable();
Volodymyr Shymanskyy 9:7369ec77a3ea 21 }
Volodymyr Shymanskyy 9:7369ec77a3ea 22
Volodymyr Shymanskyy 9:7369ec77a3ea 23 void BlynkReset()
Volodymyr Shymanskyy 9:7369ec77a3ea 24 {
Volodymyr Shymanskyy 9:7369ec77a3ea 25 wdt_enable(WDTO_15MS);
Volodymyr Shymanskyy 9:7369ec77a3ea 26 delay(50);
Volodymyr Shymanskyy 9:7369ec77a3ea 27 void(*resetFunc)(void) = 0;
Volodymyr Shymanskyy 9:7369ec77a3ea 28 resetFunc();
Volodymyr Shymanskyy 9:7369ec77a3ea 29 for(;;) {} // To make compiler happy
Volodymyr Shymanskyy 9:7369ec77a3ea 30 }
Volodymyr Shymanskyy 9:7369ec77a3ea 31
Volodymyr Shymanskyy 15:975b60f7a8ff 32 size_t BlynkFreeRam()
Volodymyr Shymanskyy 15:975b60f7a8ff 33 {
Volodymyr Shymanskyy 15:975b60f7a8ff 34 extern int __heap_start, *__brkval;
Volodymyr Shymanskyy 15:975b60f7a8ff 35 int v;
Volodymyr Shymanskyy 15:975b60f7a8ff 36 return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
Volodymyr Shymanskyy 15:975b60f7a8ff 37 }
Volodymyr Shymanskyy 15:975b60f7a8ff 38
Volodymyr Shymanskyy 15:975b60f7a8ff 39 #define _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 40 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 15:975b60f7a8ff 41
Volodymyr Shymanskyy 15:975b60f7a8ff 42 #elif defined(ARDUINO) && defined(__AVR__)
Volodymyr Shymanskyy 9:7369ec77a3ea 43
Volodymyr Shymanskyy 9:7369ec77a3ea 44 #include <Arduino.h>
Volodymyr Shymanskyy 9:7369ec77a3ea 45
Volodymyr Shymanskyy 15:975b60f7a8ff 46 void BlynkReset()
Volodymyr Shymanskyy 15:975b60f7a8ff 47 {
Volodymyr Shymanskyy 15:975b60f7a8ff 48 void(*resetFunc)(void) = 0;
Volodymyr Shymanskyy 15:975b60f7a8ff 49 resetFunc();
Volodymyr Shymanskyy 15:975b60f7a8ff 50 for(;;) {}
Volodymyr Shymanskyy 15:975b60f7a8ff 51 }
Volodymyr Shymanskyy 15:975b60f7a8ff 52
Volodymyr Shymanskyy 9:7369ec77a3ea 53 size_t BlynkFreeRam()
Volodymyr Shymanskyy 9:7369ec77a3ea 54 {
Volodymyr Shymanskyy 9:7369ec77a3ea 55 extern int __heap_start, *__brkval;
Volodymyr Shymanskyy 9:7369ec77a3ea 56 int v;
Volodymyr Shymanskyy 9:7369ec77a3ea 57 return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
Volodymyr Shymanskyy 9:7369ec77a3ea 58 }
Volodymyr Shymanskyy 9:7369ec77a3ea 59
Volodymyr Shymanskyy 15:975b60f7a8ff 60 #define _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 61 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 9:7369ec77a3ea 62
Volodymyr Shymanskyy 15:975b60f7a8ff 63 #elif defined(ARDUINO) && defined(ESP8266)
Volodymyr Shymanskyy 9:7369ec77a3ea 64
Volodymyr Shymanskyy 9:7369ec77a3ea 65 #include <Arduino.h>
Volodymyr Shymanskyy 9:7369ec77a3ea 66
Volodymyr Shymanskyy 9:7369ec77a3ea 67 size_t BlynkFreeRam()
Volodymyr Shymanskyy 9:7369ec77a3ea 68 {
Volodymyr Shymanskyy 9:7369ec77a3ea 69 return ESP.getFreeHeap();
Volodymyr Shymanskyy 9:7369ec77a3ea 70 }
Volodymyr Shymanskyy 9:7369ec77a3ea 71
Volodymyr Shymanskyy 9:7369ec77a3ea 72 void BlynkReset()
Volodymyr Shymanskyy 9:7369ec77a3ea 73 {
Volodymyr Shymanskyy 9:7369ec77a3ea 74 ESP.restart();
Volodymyr Shymanskyy 9:7369ec77a3ea 75 for(;;) {}
Volodymyr Shymanskyy 9:7369ec77a3ea 76 }
Volodymyr Shymanskyy 9:7369ec77a3ea 77
Volodymyr Shymanskyy 15:975b60f7a8ff 78 #define _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 79 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 15:975b60f7a8ff 80
Volodymyr Shymanskyy 9:7369ec77a3ea 81 #elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)
Volodymyr Shymanskyy 9:7369ec77a3ea 82
Volodymyr Shymanskyy 9:7369ec77a3ea 83 #include <Arduino.h>
Volodymyr Shymanskyy 9:7369ec77a3ea 84
Volodymyr Shymanskyy 9:7369ec77a3ea 85 size_t BlynkFreeRam()
Volodymyr Shymanskyy 9:7369ec77a3ea 86 {
Volodymyr Shymanskyy 9:7369ec77a3ea 87 return 0;
Volodymyr Shymanskyy 9:7369ec77a3ea 88 }
vshymanskyy 0:58b20b438383 89
Volodymyr Shymanskyy 9:7369ec77a3ea 90 void BlynkReset()
Volodymyr Shymanskyy 9:7369ec77a3ea 91 {
Volodymyr Shymanskyy 9:7369ec77a3ea 92 NVIC_SystemReset();
Volodymyr Shymanskyy 9:7369ec77a3ea 93 for(;;) {}
Volodymyr Shymanskyy 9:7369ec77a3ea 94 }
Volodymyr Shymanskyy 9:7369ec77a3ea 95
Volodymyr Shymanskyy 15:975b60f7a8ff 96 #define _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 97 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 9:7369ec77a3ea 98
Volodymyr Shymanskyy 15:975b60f7a8ff 99 #elif defined (ARDUINO_ARCH_ARC32)
Volodymyr Shymanskyy 9:7369ec77a3ea 100
Volodymyr Shymanskyy 15:975b60f7a8ff 101 millis_time_t BlynkMillis()
Volodymyr Shymanskyy 9:7369ec77a3ea 102 {
Volodymyr Shymanskyy 15:975b60f7a8ff 103 // TODO: Remove workaround for Intel Curie
Volodymyr Shymanskyy 15:975b60f7a8ff 104 // https://forum.arduino.cc/index.php?topic=391836.0
Volodymyr Shymanskyy 15:975b60f7a8ff 105 noInterrupts();
Volodymyr Shymanskyy 15:975b60f7a8ff 106 uint64_t t = millis();
Volodymyr Shymanskyy 15:975b60f7a8ff 107 interrupts();
Volodymyr Shymanskyy 15:975b60f7a8ff 108 return t;
Volodymyr Shymanskyy 9:7369ec77a3ea 109 }
Volodymyr Shymanskyy 9:7369ec77a3ea 110
Volodymyr Shymanskyy 15:975b60f7a8ff 111 #define _BLYNK_USE_DEFAULT_FREE_RAM
Volodymyr Shymanskyy 15:975b60f7a8ff 112 #define _BLYNK_USE_DEFAULT_RESET
Volodymyr Shymanskyy 15:975b60f7a8ff 113 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 9:7369ec77a3ea 114
Volodymyr Shymanskyy 15:975b60f7a8ff 115 #elif defined(ARDUINO) && (defined(__STM32F1__) || defined(__STM32F3__))
Volodymyr Shymanskyy 9:7369ec77a3ea 116
Volodymyr Shymanskyy 9:7369ec77a3ea 117 #include <Arduino.h>
Volodymyr Shymanskyy 9:7369ec77a3ea 118 #include <libmaple/nvic.h>
Volodymyr Shymanskyy 9:7369ec77a3ea 119
Volodymyr Shymanskyy 9:7369ec77a3ea 120 void BlynkReset()
Volodymyr Shymanskyy 9:7369ec77a3ea 121 {
Volodymyr Shymanskyy 9:7369ec77a3ea 122 nvic_sys_reset();
Volodymyr Shymanskyy 9:7369ec77a3ea 123 for(;;) {}
Volodymyr Shymanskyy 9:7369ec77a3ea 124 }
vshymanskyy 0:58b20b438383 125
Volodymyr Shymanskyy 15:975b60f7a8ff 126 #define _BLYNK_USE_DEFAULT_FREE_RAM
Volodymyr Shymanskyy 15:975b60f7a8ff 127 #define _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 128 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 15:975b60f7a8ff 129
Volodymyr Shymanskyy 15:975b60f7a8ff 130 #elif defined (PARTICLE) || defined(SPARK)
Volodymyr Shymanskyy 15:975b60f7a8ff 131
Volodymyr Shymanskyy 15:975b60f7a8ff 132 #include "application.h"
Volodymyr Shymanskyy 15:975b60f7a8ff 133
Volodymyr Shymanskyy 15:975b60f7a8ff 134 void BlynkReset()
Volodymyr Shymanskyy 15:975b60f7a8ff 135 {
Volodymyr Shymanskyy 15:975b60f7a8ff 136 System.reset();
Volodymyr Shymanskyy 15:975b60f7a8ff 137 for(;;) {} // To make compiler happy
Volodymyr Shymanskyy 15:975b60f7a8ff 138 }
Volodymyr Shymanskyy 15:975b60f7a8ff 139
Volodymyr Shymanskyy 15:975b60f7a8ff 140 #define _BLYNK_USE_DEFAULT_FREE_RAM
Volodymyr Shymanskyy 15:975b60f7a8ff 141 #define _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 142 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 9:7369ec77a3ea 143
Volodymyr Shymanskyy 16:6d9bf99b263c 144 #elif defined(__MBED__)
Volodymyr Shymanskyy 9:7369ec77a3ea 145
Volodymyr Shymanskyy 9:7369ec77a3ea 146 #include "mbed.h"
Volodymyr Shymanskyy 9:7369ec77a3ea 147
Volodymyr Shymanskyy 15:975b60f7a8ff 148 static Timer blynk_millis_timer;
Volodymyr Shymanskyy 15:975b60f7a8ff 149 static Ticker blynk_waker;
Volodymyr Shymanskyy 15:975b60f7a8ff 150
Volodymyr Shymanskyy 15:975b60f7a8ff 151 static
Volodymyr Shymanskyy 15:975b60f7a8ff 152 void blynk_wake() {
Volodymyr Shymanskyy 15:975b60f7a8ff 153 //pc.puts("(...)");
Volodymyr Shymanskyy 15:975b60f7a8ff 154 }
Volodymyr Shymanskyy 15:975b60f7a8ff 155
Volodymyr Shymanskyy 16:6d9bf99b263c 156 BLYNK_CONSTRUCTOR
Volodymyr Shymanskyy 15:975b60f7a8ff 157 static void BlynkSystemInit()
Volodymyr Shymanskyy 15:975b60f7a8ff 158 {
Volodymyr Shymanskyy 15:975b60f7a8ff 159 blynk_waker.attach(&blynk_wake, 2.0);
Volodymyr Shymanskyy 15:975b60f7a8ff 160 blynk_millis_timer.start();
Volodymyr Shymanskyy 15:975b60f7a8ff 161 }
Volodymyr Shymanskyy 15:975b60f7a8ff 162
Volodymyr Shymanskyy 15:975b60f7a8ff 163 void BlynkDelay(millis_time_t ms)
Volodymyr Shymanskyy 9:7369ec77a3ea 164 {
Volodymyr Shymanskyy 15:975b60f7a8ff 165 wait_ms(ms);
Volodymyr Shymanskyy 15:975b60f7a8ff 166 }
Volodymyr Shymanskyy 15:975b60f7a8ff 167
Volodymyr Shymanskyy 15:975b60f7a8ff 168 millis_time_t BlynkMillis()
Volodymyr Shymanskyy 15:975b60f7a8ff 169 {
Volodymyr Shymanskyy 15:975b60f7a8ff 170 return blynk_millis_timer.read_ms();
Volodymyr Shymanskyy 15:975b60f7a8ff 171 }
Volodymyr Shymanskyy 15:975b60f7a8ff 172
Volodymyr Shymanskyy 15:975b60f7a8ff 173 #define _BLYNK_USE_DEFAULT_FREE_RAM
Volodymyr Shymanskyy 15:975b60f7a8ff 174 #define _BLYNK_USE_DEFAULT_RESET
Volodymyr Shymanskyy 15:975b60f7a8ff 175
Volodymyr Shymanskyy 15:975b60f7a8ff 176 #elif defined(LINUX) && defined(RASPBERRY)
Volodymyr Shymanskyy 15:975b60f7a8ff 177 #include <stdlib.h>
Volodymyr Shymanskyy 15:975b60f7a8ff 178 #include <wiringPi.h>
Volodymyr Shymanskyy 15:975b60f7a8ff 179
Volodymyr Shymanskyy 16:6d9bf99b263c 180 BLYNK_CONSTRUCTOR
Volodymyr Shymanskyy 15:975b60f7a8ff 181 static void BlynkSystemInit()
Volodymyr Shymanskyy 15:975b60f7a8ff 182 {
Volodymyr Shymanskyy 15:975b60f7a8ff 183 wiringPiSetupGpio();
Volodymyr Shymanskyy 9:7369ec77a3ea 184 }
Volodymyr Shymanskyy 9:7369ec77a3ea 185
Volodymyr Shymanskyy 9:7369ec77a3ea 186 void BlynkReset()
Volodymyr Shymanskyy 9:7369ec77a3ea 187 {
Volodymyr Shymanskyy 15:975b60f7a8ff 188 exit(1);
Volodymyr Shymanskyy 9:7369ec77a3ea 189 for(;;) {} // To make compiler happy
Volodymyr Shymanskyy 9:7369ec77a3ea 190 }
Volodymyr Shymanskyy 9:7369ec77a3ea 191
Volodymyr Shymanskyy 15:975b60f7a8ff 192 #define _BLYNK_USE_DEFAULT_FREE_RAM
Volodymyr Shymanskyy 15:975b60f7a8ff 193 #define _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 194 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 15:975b60f7a8ff 195
Volodymyr Shymanskyy 15:975b60f7a8ff 196 #elif defined(LINUX)
Volodymyr Shymanskyy 15:975b60f7a8ff 197
Volodymyr Shymanskyy 15:975b60f7a8ff 198 #define _POSIX_C_SOURCE 200809L
Volodymyr Shymanskyy 15:975b60f7a8ff 199 #include <stdlib.h>
Volodymyr Shymanskyy 15:975b60f7a8ff 200 #include <time.h>
Volodymyr Shymanskyy 15:975b60f7a8ff 201 #include <unistd.h>
Volodymyr Shymanskyy 15:975b60f7a8ff 202
Volodymyr Shymanskyy 15:975b60f7a8ff 203 void BlynkReset()
Volodymyr Shymanskyy 15:975b60f7a8ff 204 {
Volodymyr Shymanskyy 15:975b60f7a8ff 205 exit(1);
Volodymyr Shymanskyy 15:975b60f7a8ff 206 for(;;) {} // To make compiler happy
Volodymyr Shymanskyy 15:975b60f7a8ff 207 }
Volodymyr Shymanskyy 15:975b60f7a8ff 208
Volodymyr Shymanskyy 15:975b60f7a8ff 209 void BlynkDelay(millis_time_t ms)
Volodymyr Shymanskyy 15:975b60f7a8ff 210 {
Volodymyr Shymanskyy 15:975b60f7a8ff 211 usleep(ms * 1000);
Volodymyr Shymanskyy 15:975b60f7a8ff 212 }
Volodymyr Shymanskyy 15:975b60f7a8ff 213
Volodymyr Shymanskyy 15:975b60f7a8ff 214 millis_time_t BlynkMillis()
Volodymyr Shymanskyy 15:975b60f7a8ff 215 {
Volodymyr Shymanskyy 15:975b60f7a8ff 216 struct timespec ts;
Volodymyr Shymanskyy 15:975b60f7a8ff 217 clock_gettime(CLOCK_MONOTONIC, &ts );
Volodymyr Shymanskyy 15:975b60f7a8ff 218 return ( ts.tv_sec * 1000 + ts.tv_nsec / 1000000L );
Volodymyr Shymanskyy 15:975b60f7a8ff 219 }
Volodymyr Shymanskyy 15:975b60f7a8ff 220
Volodymyr Shymanskyy 15:975b60f7a8ff 221 #define _BLYNK_USE_DEFAULT_FREE_RAM
Volodymyr Shymanskyy 15:975b60f7a8ff 222
Volodymyr Shymanskyy 9:7369ec77a3ea 223 #else
Volodymyr Shymanskyy 9:7369ec77a3ea 224
Volodymyr Shymanskyy 9:7369ec77a3ea 225 #if defined(BLYNK_DEBUG_ALL)
Volodymyr Shymanskyy 9:7369ec77a3ea 226 #warning "Need to implement board-specific utilities"
Volodymyr Shymanskyy 9:7369ec77a3ea 227 #endif
Volodymyr Shymanskyy 9:7369ec77a3ea 228
Volodymyr Shymanskyy 15:975b60f7a8ff 229 #define _BLYNK_USE_DEFAULT_FREE_RAM
Volodymyr Shymanskyy 15:975b60f7a8ff 230 #define _BLYNK_USE_DEFAULT_RESET
Volodymyr Shymanskyy 15:975b60f7a8ff 231 #define _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 232 #define _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 15:975b60f7a8ff 233
Volodymyr Shymanskyy 15:975b60f7a8ff 234 #endif
Volodymyr Shymanskyy 15:975b60f7a8ff 235
Volodymyr Shymanskyy 15:975b60f7a8ff 236 #ifdef _BLYNK_USE_DEFAULT_DELAY
Volodymyr Shymanskyy 15:975b60f7a8ff 237 void BlynkDelay(millis_time_t ms)
Volodymyr Shymanskyy 15:975b60f7a8ff 238 {
Volodymyr Shymanskyy 15:975b60f7a8ff 239 return delay(ms);
Volodymyr Shymanskyy 15:975b60f7a8ff 240 }
Volodymyr Shymanskyy 15:975b60f7a8ff 241 #endif
Volodymyr Shymanskyy 15:975b60f7a8ff 242
Volodymyr Shymanskyy 15:975b60f7a8ff 243 #ifdef _BLYNK_USE_DEFAULT_MILLIS
Volodymyr Shymanskyy 15:975b60f7a8ff 244 millis_time_t BlynkMillis()
Volodymyr Shymanskyy 15:975b60f7a8ff 245 {
Volodymyr Shymanskyy 15:975b60f7a8ff 246 return millis();
Volodymyr Shymanskyy 15:975b60f7a8ff 247 }
Volodymyr Shymanskyy 15:975b60f7a8ff 248 #endif
Volodymyr Shymanskyy 15:975b60f7a8ff 249
Volodymyr Shymanskyy 15:975b60f7a8ff 250 #ifdef _BLYNK_USE_DEFAULT_FREE_RAM
Volodymyr Shymanskyy 9:7369ec77a3ea 251 size_t BlynkFreeRam()
Volodymyr Shymanskyy 9:7369ec77a3ea 252 {
Volodymyr Shymanskyy 9:7369ec77a3ea 253 return 0;
Volodymyr Shymanskyy 9:7369ec77a3ea 254 }
Volodymyr Shymanskyy 15:975b60f7a8ff 255 #endif
Volodymyr Shymanskyy 9:7369ec77a3ea 256
Volodymyr Shymanskyy 15:975b60f7a8ff 257 #ifdef _BLYNK_USE_DEFAULT_RESET
Volodymyr Shymanskyy 9:7369ec77a3ea 258 void BlynkReset()
Volodymyr Shymanskyy 9:7369ec77a3ea 259 {
Volodymyr Shymanskyy 9:7369ec77a3ea 260 for(;;) {} // To make compiler happy
Volodymyr Shymanskyy 9:7369ec77a3ea 261 }
Volodymyr Shymanskyy 9:7369ec77a3ea 262 #endif
vshymanskyy 0:58b20b438383 263
vshymanskyy 0:58b20b438383 264 void BlynkFatal()
vshymanskyy 0:58b20b438383 265 {
Volodymyr Shymanskyy 15:975b60f7a8ff 266 BlynkDelay(10000L);
vshymanskyy 0:58b20b438383 267 BlynkReset();
vshymanskyy 0:58b20b438383 268 }
Volodymyr Shymanskyy 15:975b60f7a8ff 269