//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ int mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame) { char buff[PACKET_BUFF_SIZE]; int remaining, timeouts; ssize_t len, nread; if (handle == NULL || frame == NULL) { fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__); return MBUS_RECV_RESULT_ERROR; } // Make sure serial connection is open if (isatty(handle->fd) == 0) { fprintf(stderr, "%s: Serial connection is not available.\n", __PRETTY_FUNCTION__); return MBUS_RECV_RESULT_ERROR; } memset((void *)buff, 0, sizeof(buff)); // // read data until a packet is received // remaining = 1; // start by reading 1 byte len = 0; timeouts = 0; do { if (len + remaining > PACKET_BUFF_SIZE) { // avoid out of bounds access return MBUS_RECV_RESULT_ERROR; } //printf("%s: Attempt to read %d bytes [len = %d]\n", __PRETTY_FUNCTION__, remaining, len); if ((nread = read(handle->fd, &buff[len], remaining)) == -1) { // fprintf(stderr, "%s: aborting recv frame (remaining = %d, len = %d, nread = %d)\n", // __PRETTY_FUNCTION__, remaining, len, nread); return MBUS_RECV_RESULT_ERROR; } // printf("%s: Got %d byte [remaining %d, len %d]\n", __PRETTY_FUNCTION__, nread, remaining, len); if (nread == 0) { timeouts++; if (timeouts >= 3) { // abort to avoid endless loop fprintf(stderr, "%s: Timeout\n", __PRETTY_FUNCTION__); break; } } if (len > (SSIZE_MAX-nread)) { // avoid overflow return MBUS_RECV_RESULT_ERROR; } len += nread; } while ((remaining = mbus_parse(frame, buff, len)) > 0); if (len == 0) { // No data received return MBUS_RECV_RESULT_TIMEOUT; } // // call the receive event function, if the callback function is registered // if (_mbus_recv_event) _mbus_recv_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); if (remaining != 0) { // Would be OK when e.g. scanning the bus, otherwise it is a failure. // printf("%s: M-Bus layer failed to receive complete data.\n", __PRETTY_FUNCTION__); return MBUS_RECV_RESULT_INVALID; } if (len == -1) { fprintf(stderr, "%s: M-Bus layer failed to parse data.\n", __PRETTY_FUNCTION__); return MBUS_RECV_RESULT_ERROR; } return MBUS_RECV_RESULT_OK; }
//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ int mbus_serial_recv_frame(SoftwareSerial *handle, mbus_frame *frame) { uint8_t buff[PACKET_BUFF_SIZE]; int len, remaining, nread, timeouts; printf_P(PSTR("%s: Entered \n"), __PRETTY_FUNCTION__); if (handle == NULL || frame == NULL) { printf_P(PSTR("%s: Invalid parameter.\n"), __PRETTY_FUNCTION__); return -1; } memset(buff, 0, sizeof(buff)); // // read data until a packet is received // remaining = 1; // start by reading 1 byte len = 0; timeouts = 0; printf_P(PSTR("%s: Entered3 \n"), __PRETTY_FUNCTION__); do { printf_P(PSTR("%s: Attempt to read %d bytes [len = %d]\n"), __PRETTY_FUNCTION__, remaining, len); while(handle->available()>0 && len<PACKET_BUFF_SIZE) { buff[len] = handle->read(); len++; } } while ((remaining = mbus_parse(frame, buff, len)) > 0); if (len == 0) { // No data received return -1; } // // call the receive event function, if the callback function is registered // if (_mbus_recv_event) _mbus_recv_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); if (remaining != 0) { // Would be OK when e.g. scanning the bus, otherwise it is a failure. printf_P(PSTR("%s: M-Bus layer failed to receive complete data.\n"), __PRETTY_FUNCTION__); return -2; } if (len == -1) { printf_P(PSTR("%s: M-Bus layer failed to parse data.\n"), __PRETTY_FUNCTION__); return -1; } return 0; }