Example #1
0
/* allocate buffer but free unless able to read and parse nlm fully */
static GOOD_OR_BAD Get_and_Parse_Pipe( FILE_DESCRIPTOR_OR_ERROR file_descriptor, struct netlink_parse * nlp )
{
	struct nlmsghdr peek_nlm ;
	struct nlmsghdr * nlm ;
	size_t payload_length ;

	// first read start of message to get length and details
	if ( read( file_descriptor, &peek_nlm, W1_NLM_LENGTH ) != W1_NLM_LENGTH ) {
		ERROR_DEBUG("Pipe (w1) read header error");
		return gbBAD ;
	}

	LEVEL_DEBUG("Pipe header: len=%u type=%u seq=%u|%u pid=%u ",peek_nlm.nlmsg_len,peek_nlm.nlmsg_type,NL_BUS(peek_nlm.nlmsg_seq),NL_SEQ(peek_nlm.nlmsg_seq),peek_nlm.nlmsg_pid);

	// allocate space
	nlm = owmalloc( peek_nlm.nlmsg_len ) ;
	nlp->nlm = nlm ;
	if ( nlm == NULL ) {
		LEVEL_DEBUG("Netlink (w1) Cannot allocate %d byte buffer for data", peek_nlm.nlmsg_len ) ;
		return gbBAD ;
	}

	memcpy( nlm, &peek_nlm, W1_NLM_LENGTH ) ; // copy header
	// read rest of packet
	if ( peek_nlm.nlmsg_len <= W1_NLM_LENGTH ) {
		owfree(nlm) ;
		LEVEL_DEBUG( "W1 packet error. Length is too short." ) ;
		return gbBAD ;
	}
	payload_length = peek_nlm.nlmsg_len - W1_NLM_LENGTH ;
	if ( read( file_descriptor, NLMSG_DATA(nlm), payload_length ) != (ssize_t) payload_length ) {
		owfree(nlm) ;
		nlp->nlm = NULL ;
		ERROR_DEBUG("Pipe (w1) read payload error");
		return gbBAD ;
	}

	if ( BAD( Netlink_Parse_Buffer( nlp )) ) {
		LEVEL_DEBUG("Buffer parsing error");
		owfree(nlm) ;
		nlp->nlm = NULL ;
		return gbBAD ;
	}

	// Good, the receiving routine should owfree buffer
	LEVEL_DEBUG("Pipe read --------------------");
	Netlink_Parse_Show( nlp ) ;
	return gbGOOD ;
}
static ZERO_OR_ERROR OW_read_external_script( struct sensor_node * sensor_n, struct property_node * property_n, struct one_wire_query * owq )
{
	char cmd[PATH_MAX+1] ;
	struct parsedname * pn = PN(owq) ;
	FILE * script_f ;
	int snp_return ;
	ZERO_OR_ERROR zoe ;
	
	
	// load the command script and arguments
	if ( pn->sparse_name == NULL ) {
		// not a text sparse name
		snp_return =
		snprintf( cmd, PATH_MAX+1, "%s %s %s %d %s %d %d %s %s",
			property_n->read, // command
			sensor_n->name, // sensor name
			property_n->property, // property,
			pn->extension, // extension
			"read", // mode
			(int) OWQ_size(owq), // size
			(int) OWQ_offset(owq), // offset
			sensor_n->data, // sensor-specific data
			property_n->data // property-specific data
		) ;
	} else {
		snp_return =
		snprintf( cmd, PATH_MAX+1, "%s %s %s %s %s %d %d %s %s",
			property_n->read, // command
			sensor_n->name, // sensor name
			property_n->property, // property,
			pn->sparse_name, // extension
			"read", // mode
			(int) OWQ_size(owq), // size
			(int) OWQ_offset(owq), // offset
			sensor_n->data, // sensor-specific data
			property_n->data // property-specific data
		) ;
	}

	if ( snp_return < 0 ) {
		LEVEL_DEBUG("Problem creating script string for %s/%s",sensor_n->name,property_n->property) ;
		return -EINVAL ;
	}
	
	script_f = popen( cmd, "r" ) ;
	if ( script_f == NULL ) {
		ERROR_DEBUG("Cannot create external program link for reading %s/%s",sensor_n->name,property_n->property);
		return -EIO ;
	}
	
	zoe = OW_script_read( script_f, owq ) ;
	
	fclose( script_f ) ;
	return zoe ;
}
Example #3
0
static int Get_HA7_response( struct addrinfo *now, char * name )
{
	struct timeval tv = { 50, 0 };
	FILE_DESCRIPTOR_OR_ERROR file_descriptor;
	struct HA7_response ha7_response ;

	struct sockaddr_in from ;
	socklen_t fromlen = sizeof(struct sockaddr_in) ;
	int on = 1;

	file_descriptor = socket(now->ai_family, now->ai_socktype, now->ai_protocol) ;
	if ( FILE_DESCRIPTOR_NOT_VALID(file_descriptor) ) {
		ERROR_DEBUG("Cannot get socket file descriptor for broadcast.");
		return 1;
	}
//	fcntl (file_descriptor, F_SETFD, FD_CLOEXEC); // for safe forking
	if (setsockopt(file_descriptor, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) {
		ERROR_DEBUG("Cannot set socket option for broadcast.");
		return 1;
	}
	if (sendto(file_descriptor, "HA\000\001", 4, 0, now->ai_addr, now->ai_addrlen)
		!= 4) {
		ERROR_CONNECT("Trouble sending broadcast message");
		return 1;
	}

	/* now read */
	if ( udp_read(file_descriptor, &ha7_response, sizeof(struct HA7_response), &tv, &from, &fromlen) != sizeof(struct HA7_response) ) {
		LEVEL_CONNECT("HA7 response bad length");
		return 1;
	}

	if ( Test_HA7_response( &ha7_response ) ) {
		return 1 ;
	}

	UCLIBCLOCK ;
	snprintf(name,INET_ADDRSTRLEN+20,"%s:%d",inet_ntoa(from.sin_addr),ntohs(ha7_response.port));
	UCLIBCUNLOCK ;

	return 0 ;
}
Example #4
0
GOOD_OR_BAD W1_Browse( void )
{
	pthread_t thread_dispatch ;

	if ( pthread_create(&thread_dispatch, DEFAULT_THREAD_ATTR, W1_Dispatch, NULL ) != 0 ) {
		ERROR_DEBUG("Couldn't create netlink monitoring thread");
		return gbBAD ;
	}

	return gbGOOD ;
}
Example #5
0
GOOD_OR_BAD Netlink_Parse_Get( struct netlink_parse * nlp )
{
	struct nlmsghdr peek_nlm ;

	// first peek at message to get length and details
	LEVEL_DEBUG("Wait to peek at message");
	int recv_len = recv( Inbound_Control.w1_monitor->pown->file_descriptor, &peek_nlm, W1_NLM_LENGTH, MSG_PEEK );

	// Set time of last read
	_MUTEX_LOCK(Inbound_Control.w1_monitor->master.w1_monitor.read_mutex) ;
	timernow( &(Inbound_Control.w1_monitor->master.w1_monitor.last_read) );
	_MUTEX_UNLOCK(Inbound_Control.w1_monitor->master.w1_monitor.read_mutex) ;

	LEVEL_DEBUG("Pre-parse header: %u bytes len=%u type=%u seq=%u|%u pid=%u",recv_len,peek_nlm.nlmsg_len,peek_nlm.nlmsg_type,NL_BUS(peek_nlm.nlmsg_seq),NL_SEQ(peek_nlm.nlmsg_seq),peek_nlm.nlmsg_pid);
	if (recv_len < 0) {
		ERROR_DEBUG("Netlink (w1) recv header error");
		return gbBAD ;
	}

	// allocate space
	nlp->nlm = owmalloc( peek_nlm.nlmsg_len ) ;
	if ( nlp->nlm == NULL ) {
		LEVEL_DEBUG("Netlink (w1) Cannot allocate %d byte buffer for data",peek_nlm.nlmsg_len) ;
		return gbBAD ;
	}

	// read whole packet
	recv_len = recv( Inbound_Control.w1_monitor->pown->file_descriptor, &(nlp->nlm[0]), peek_nlm.nlmsg_len, 0 );
	if (recv_len == -1) {
		ERROR_DEBUG("Netlink (w1) recv body error");
		return gbBAD ;
	}

	if ( GOOD( Netlink_Parse_Buffer( nlp )) ) {
		LEVEL_DEBUG("Netlink read -----------------");
		Netlink_Parse_Show( nlp ) ;
		return gbGOOD ;
	}
	return gbBAD ;
}
Example #6
0
/* Device-specific functions */
GOOD_OR_BAD W1_monitor_detect(struct port_in *pin)
{
	struct connection_in * in = pin->first ;
	struct timeval tvslack = { 1, 0 } ; // 1 second
	
	pin->file_descriptor = FILE_DESCRIPTOR_BAD;
	pin->type = ct_none ;
	in->iroutines.detect = W1_monitor_detect;
	in->Adapter = adapter_w1_monitor;	/* OWFS assigned value */
	in->iroutines.reset = NO_RESET_ROUTINE;
	in->iroutines.next_both = NO_NEXT_BOTH_ROUTINE;
	in->iroutines.PowerByte = NO_POWERBYTE_ROUTINE;
	in->iroutines.ProgramPulse = NO_PROGRAMPULSE_ROUTINE;
	in->iroutines.sendback_data = NO_SENDBACKDATA_ROUTINE;
	in->iroutines.sendback_bits = NO_SENDBACKBITS_ROUTINE;
	in->iroutines.select = NO_SELECT_ROUTINE;
	in->iroutines.select_and_sendback = NO_SELECTANDSENDBACK_ROUTINE;
	in->iroutines.set_config = NO_SET_CONFIG_ROUTINE;
	in->iroutines.get_config = NO_GET_CONFIG_ROUTINE;
	in->iroutines.reconnect = NO_RECONNECT_ROUTINE;
	in->iroutines.close = W1_monitor_close;
	in->iroutines.verify = NO_VERIFY_ROUTINE ;
	in->iroutines.flags = ADAP_FLAG_sham;
	in->adapter_name = "W1 monitor";
	pin->busmode = bus_w1_monitor ;
	
	RETURN_BAD_IF_BAD( w1_monitor_in_use(in) ) ;
	
	// Initial setup
	Inbound_Control.w1_monitor = in ; // essentially a global pointer to the w1_monitor entry
	_MUTEX_INIT(in->master.w1_monitor.seq_mutex);
	_MUTEX_INIT(in->master.w1_monitor.read_mutex);

	timernow( &(in->master.w1_monitor.last_read) );
	timeradd( &(in->master.w1_monitor.last_read), &tvslack, &(in->master.w1_monitor.last_read) );

	in->master.w1_monitor.seq = SEQ_INIT ;
	in->master.w1_monitor.pid = 0 ;
	
	w1_bind(in) ; // sets in->file_descriptor
	if ( FILE_DESCRIPTOR_NOT_VALID( in->pown->file_descriptor ) ) {
		ERROR_DEBUG("Netlink problem -- are you root?");
		Inbound_Control.w1_monitor = NO_CONNECTION ;
		return gbBAD ;
	}
	
	return W1_Browse() ; // creates thread that runs forever.
}