VictronVEDirectArduino icon indicating copy to clipboard operation
VictronVEDirectArduino copied to clipboard

Null pointer read exception reboot loop with use of a ESP32 Board

Open C-razyBlue opened this issue 6 years ago • 4 comments

I got reboot loop crashes with the use of this library on a ESP32 board...

I managed to solve this by adding two null pointer - if's checks after the two strtok's in the souce code... Now it's working fine...

label = strtok(line, "\t"); // Null pointer check, ESP32 Crashed without this if (label) {

value_str = strtok(0, "\t"); // Null pointer check, ESP32 Crashed without this if (value_str) {

Thanks for this great library !!!

C-razyBlue avatar Jan 04 '20 14:01 C-razyBlue

Many thanks! Would you like to pull a copy and push the fix back to the code base? Or I can add it in. Let me know.

winginitau avatar Feb 15 '20 01:02 winginitau

Has this issue been merged / resolved yet? I was having the same issue until i stumbled across this but am not sure where the } should go

007trains avatar Feb 21 '20 11:02 007trains

You can add it in, I adjusted the VEDirect::read code like this to work on the ESP32:

int32_t VEDirect::read(uint8_t target) {
	// Read VE.Direct lines from the serial port
	// Search for the label specified by enum target
	// Extract and return the corresponding value
	// If value is "ON" return 1. If "OFF" return 0;

	uint16_t loops = VED_MAX_READ_LOOPS;
	uint8_t lines = VED_MAX_READ_LINES;
	int32_t ret = 0;					// The value to be returned
	char line[VED_LINE_SIZE] = "\0";	// Line buffer
	uint8_t idx = 0;					// Line buffer index
	char* label;
	char* value_str;
	int8_t b;							// byte read from the stream

	VESerial.begin(VED_BAUD_RATE);

	while (lines > 0) {
		if (VESerial.available()) {
			while (loops > 0) {
				b = VESerial.read();
				if ((b == -1) || (b == '\r')) { 	// Ignore '\r' and empty reads
					loops--;
				} else {
					if (b == '\n') { 				// EOL
						break;
					} else {
						if (idx < VED_LINE_SIZE) {
							line[idx++] = b;		// Add it to the buffer
						} else {
							return 0;				// Buffer overrun
						}
					}
				}
			}
			line[idx] = '\0';						// Terminate the string

			// Line in buffer
			if (target == VE_DUMP) {
				// Diagnostic routine - just print to Serial0;
				Serial.println(line);
				// Continue on rather than break to reset for next line
			}

			label = strtok(line, "\t");

			// Null pointer check, ESP32 Crashed without this
			if (label)									
			{
				if (strcmp_P(label, ved_labels[target]) == 0) {
					value_str = strtok(0, "\t");

					// Null pointer check, ESP32 Crashed without this
					if (value_str)						
					{
						if (value_str[0] == 'O') { 		//ON OFF type
							if (value_str[1] == 'N') {
								ret = 1;	// ON
								break;
							}
							else {
								ret = 0;	// OFF
								break;
							}
						}
						else {
							sscanf(value_str, "%ld", &ret);
							break;
						}
					}
				}
				else {			// Line not of interest
					lines--;
					loops = VED_MAX_READ_LOOPS;
					line[0] = '\0';
					idx = 0;
				}
			}
		}
	}
	return ret;
}

I only have a crashing ESP32 now still when Serial is not connected to a VE Direct device, i will try to solve this problem soon...

C-razyBlue avatar Feb 23 '20 19:02 C-razyBlue

Did you manage to solve the issue with the disconnected device? Thx.

AllInProgress avatar Feb 21 '24 20:02 AllInProgress