void message_filter::check_new_data (NET_Packet & packet) { u32 tmp_old_pos = packet.r_tell(); msg_type_subtype_t packet_mtype; packet_mtype.import (packet); if (packet_mtype.msg_type == M_EVENT_PACK) { NET_Packet tmp_packet; while (!packet.r_eof()) { tmp_packet.B.count = packet.r_u8(); packet.r (tmp_packet.B.data, tmp_packet.B.count); packet_mtype.import(tmp_packet); R_ASSERT2(packet_mtype.msg_type != M_EVENT_PACK, "M_EVENT_PACK in M_EVENT_PACK"); dbg_print_msg (tmp_packet, packet_mtype); filters_map_t::iterator tmp_iter = m_filters.find(packet_mtype); if (tmp_iter != m_filters.end()) { tmp_iter->second(packet_mtype.msg_type, packet_mtype.msg_subtype, tmp_packet); } } } else { dbg_print_msg (packet, packet_mtype); filters_map_t::iterator tmp_iter = m_filters.find(packet_mtype); if (tmp_iter != m_filters.end()) { tmp_iter->second(packet_mtype.msg_type, packet_mtype.msg_subtype, packet); } } packet.r_seek (tmp_old_pos); }
/** * @brief Reads RSI message from RS-485 bus, checks CRC * * @param fd File descriptor for RSI session (UART) * @param buffer Buffer to hold read message * * @return */ uInt16_t rsi_read( uInt16_t fd, uInt8_t *buffer ) { if (fd == -1) return -1; uInt16_t count; sInt32_t validRsiFrame = STATUS_FAILURE; tcflush(fd, TCIFLUSH); //in half duplex mode, ignore chars we sent and may have received... rs485_rcvEnable(); while (validRsiFrame != STATUS_SUCCESS) { //rs485UartVminVtime( fd, 0, 0 ); //no block buffer[0] = 0; // wait for RSI SOF... do { count = rs485_read(fd, buffer, 1); if (count < 0) puts("-"); delayuS(10); //don't burn up all the CPU if nonblocking read enabled if (count == -1 && errno != EAGAIN) //FIXME needs work puts("unhandled read error!\n"); } while (buffer[0] != RSI_SOF); rs485UartVminVtime( fd, RSI_MAX_FRAME_SIZE, 1 ); //wait for max size frame (or) 0.1 sec timeout //now capture remainder of packet. length is not fully known! // if bit 7 of Type = 1: indicates 2 length bytes // Length bytes indicates # data bytes // tricky: FCS can be one or 2 bytes, not always indicated by cmd Type!! //BETTER?: if we can rely on intercharacter timeout (0.1 sec) then // ask for max cmd size & wait for timeout... //KERNEL BUG? current timeout appears to be about 2 seconds (?) count = rs485_read(fd, &buffer[1], RSI_MAX_FRAME_SIZE-1); //should return after 0.1 sec printf("total bytes counted = %d\n", count+1); //RS485 Bytes received dbg_print_msg( 0, buffer, count+1 ); //validate message CRC/checksum validRsiFrame = rsi_validateFrame( &buffer[1], count); } //waiting for validRsiFrame //gpio_setValue( RS485_LED_RED, 0 ); rs485_rcvDisable(); return (count+1); }
/** * @brief Writes RSI message to RS-485 bus * * @param fd File descriptor for RSI session * @param buffer Buffer containing message to write * @param numBytes Number of bytes to write * * @return */ uInt16_t rsi_write( uInt16_t fd, uInt8_t *buffer, uInt16_t numBytes ) { if (fd == -1) return -1; rs485_xmitEnable(); //half duplex mode, enable Tx rs485_write( fd, buffer, numBytes ); tcdrain(fd); //FIXME: force the write to complete - do we need it? dbg_print_msg( 1, buffer, numBytes ); //FIXME! at 9600 baud, need to ensure Tx is done before disabling transceiver! delayuS(100000); //9600 baud * 64 bytes max = 66 mS ==> wait 100 mSec rs485_xmitDisable(); }