kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			pixma: add AXIS pixma.conf support
Support reading configuration from pixma conf. Also fix some debug messages.pixma-axis-driver^2
							rodzic
							
								
									7de193c9a4
								
							
						
					
					
						commit
						92e2ef6270
					
				|  | @ -98,13 +98,13 @@ static ssize_t receive_packet(int socket, void *packet, size_t len, struct socka | |||
|   case 0: | ||||
|     return 0; | ||||
|   case -1: | ||||
|     DBG(LOG_CRIT, "select() failed"); | ||||
|     DBG(LOG_CRIT, "select() failed\n"); | ||||
|     return 0; | ||||
|   default: | ||||
|     received = recvfrom(socket, packet, len, 0, (struct sockaddr *)from, &from_len); | ||||
|     if (received < 0) { | ||||
|       DBG(LOG_CRIT, "Error receiving packet"); | ||||
|       exit(2); | ||||
|       DBG(LOG_CRIT, "Error receiving packet\n"); | ||||
|       return 0; | ||||
|     } | ||||
| /*#ifdef DEBUG
 | ||||
|     int i; | ||||
|  | @ -127,7 +127,7 @@ static ssize_t axis_send_wimp(int udp_socket, uint8_t cmd, void *data, uint16_t | |||
|   memcpy(packet + sizeof(struct axis_wimp_header), data, len); | ||||
|   ret = sendto(udp_socket, packet, sizeof(struct axis_wimp_header) + len, 0, addr, addrlen); | ||||
|   if (ret != (int)sizeof(struct axis_wimp_header) + len) { | ||||
|     DBG(LOG_CRIT, "Unable to send UDP packet"); | ||||
|     DBG(LOG_CRIT, "Unable to send UDP packet\n"); | ||||
|     return ret; | ||||
|   } | ||||
| 
 | ||||
|  | @ -174,12 +174,12 @@ static int create_udp_socket(uint32_t addr, uint16_t *source_port) { | |||
| 
 | ||||
|   udp_socket = socket(AF_INET, SOCK_DGRAM, 0); | ||||
|   if (udp_socket < 0) { | ||||
|     DBG(LOG_CRIT, "Unable to create UDP socket"); | ||||
|     DBG(LOG_CRIT, "Unable to create UDP socket\n"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   if (setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, &enable, sizeof(enable))) { | ||||
|     DBG(LOG_CRIT, "Unable to enable broadcast"); | ||||
|     DBG(LOG_CRIT, "Unable to enable broadcast\n"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|  | @ -187,7 +187,7 @@ static int create_udp_socket(uint32_t addr, uint16_t *source_port) { | |||
|   address.sin_port = 0; /* random */ | ||||
|   address.sin_addr.s_addr = addr; | ||||
|   if (bind(udp_socket, (struct sockaddr *)&address, sizeof(address)) < 0) { | ||||
|     DBG(LOG_CRIT, "Unable to bind UDP socket"); | ||||
|     DBG(LOG_CRIT, "Unable to bind UDP socket\n"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|  | @ -210,7 +210,7 @@ static int get_server_status(int udp_socket, uint32_t addr, uint16_t remote_port | |||
|   /* connect the socket to this print server only */ | ||||
| 
 | ||||
|   if (connect(udp_socket, (struct sockaddr *)&address, sizeof(address)) < 0) { | ||||
|     DBG(LOG_CRIT, "Unable to connect UDP socket"); | ||||
|     DBG(LOG_CRIT, "Unable to connect UDP socket\n"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|  | @ -241,13 +241,17 @@ static int get_device_name(int udp_socket, uint32_t addr, uint16_t remote_port, | |||
|   /* connect the socket to this print server only */ | ||||
| 
 | ||||
|   if (connect(udp_socket, (struct sockaddr *)&address, sizeof(address)) < 0) { | ||||
|     DBG(LOG_CRIT, "Unable to connect UDP socket"); | ||||
|     DBG(LOG_CRIT, "Unable to connect UDP socket\n"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   buf[0] = '\0'; | ||||
|   /* get device name */ | ||||
|   if (axis_wimp_get(udp_socket, remote_port, WIMP_GET_NAME, 1, buf, sizeof(buf))) | ||||
|     DBG(LOG_NOTICE, "Error getting device name\n"); | ||||
|     { | ||||
|       DBG(LOG_NOTICE, "Error getting device name\n"); | ||||
|       return -1; | ||||
|     } | ||||
|   DBG(LOG_INFO, "name=%s\n", buf); | ||||
| 
 | ||||
|   strncpy(devname, buf, devname_len); | ||||
|  | @ -270,7 +274,7 @@ static int send_discover(int udp_socket, uint32_t addr, uint16_t source_port) { | |||
| 
 | ||||
|   ret = axis_send_wimp(udp_socket, WIMP_SERVER_INFO, get_info, sizeof(get_info), (struct sockaddr *)&address, sizeof(address)); | ||||
|   if (ret) | ||||
|     DBG(LOG_CRIT, "Unable to send discover packet"); | ||||
|     DBG(LOG_CRIT, "Unable to send discover packet\n"); | ||||
| 
 | ||||
|   return ret; | ||||
| } | ||||
|  | @ -280,7 +284,7 @@ static int send_broadcasts(int udp_socket, uint16_t source_port) { | |||
|   int num_sent = 0; | ||||
| 
 | ||||
|   if (getifaddrs(&ifaddr) == -1) { | ||||
|     DBG(LOG_CRIT, "Unable to obtain network interface list"); | ||||
|     DBG(LOG_CRIT, "Unable to obtain network interface list\n"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|  | @ -313,7 +317,7 @@ int axis_send_cmd(int tcp_socket, uint8_t cmd, void *data, uint16_t len) { | |||
|     fprintf(stderr, "%02x ", packet[i]); | ||||
|   fprintf(stderr, "\n"); | ||||
|   if (ret < 0) { | ||||
|     perror("Error sending packet"); | ||||
|     DBG(LOG_NOTICE, "Error sending packet\n"); | ||||
|     return ret; | ||||
|   } | ||||
| 
 | ||||
|  | @ -326,7 +330,7 @@ int axis_send_cmd(int tcp_socket, uint8_t cmd, void *data, uint16_t len) { | |||
|     fprintf(stderr, "%02x ", packet[i]); | ||||
|   fprintf(stderr, "\n"); | ||||
|   if (ret < 0) { | ||||
|     perror("Error sending packet"); | ||||
|     DBG(LOG_NOTICE, "Error sending packet\n"); | ||||
|     return ret; | ||||
|   } | ||||
| 
 | ||||
|  | @ -408,6 +412,55 @@ retry: | |||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| parse_uri(const char *uri, struct sockaddr_in *address) | ||||
| { | ||||
|   const char *uri_host, *uri_port; | ||||
|   char host[256]; | ||||
|   size_t host_len; | ||||
|   int port; | ||||
| 
 | ||||
|   if (strncmp(uri, "axis://", 7)) | ||||
|     { | ||||
|       DBG(LOG_INFO, "Invalid protocol in uri\n"); | ||||
|       return -1; | ||||
|     } | ||||
|   uri_host = uri + 7; | ||||
| 
 | ||||
|   port = AXIS_SCAN_PORT; | ||||
|   uri_port = strchr(uri_host, ':'); | ||||
|   if (uri_port) | ||||
|     { | ||||
|       sscanf(uri_port, ":%d", &port); | ||||
|       host_len = uri_port - uri_host; | ||||
|     } | ||||
|   else | ||||
|     host_len = strlen(uri_host); | ||||
|   if (host_len > 255) | ||||
|     host_len = 255; | ||||
|   strncpy(host, uri_host, host_len); | ||||
|   host[host_len] = '\0'; | ||||
| 
 | ||||
|   /* resolve host */ | ||||
|   struct addrinfo *result; | ||||
|   struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP }; | ||||
|   int err = getaddrinfo(host, NULL, &hints, &result); | ||||
|   if (err) | ||||
|     { | ||||
|       DBG(LOG_INFO, "getaddrinfo failed: %s\n", gai_strerror(err)); | ||||
|       return -1; | ||||
|     } | ||||
|   struct sockaddr_in *addr = (struct sockaddr_in *) result->ai_addr; | ||||
|   DBG(LOG_DEBUG, "host=%s, ip=%s, port=%d\n", host, inet_ntoa(addr->sin_addr), port); | ||||
|   address->sin_family = AF_INET; | ||||
|   address->sin_port = htons(port); | ||||
|   address->sin_addr = addr->sin_addr; | ||||
| 
 | ||||
|   freeaddrinfo(result); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Find AXIS printservers with Canon support | ||||
|  | @ -432,13 +485,61 @@ sanei_axis_find_devices (const char **conf_devices, | |||
|   char uri[256]; | ||||
|   uint8_t packet[MAX_PACKET_DATA_SIZE]; | ||||
|   struct sockaddr_in from; | ||||
|   uint16_t source_port, remote_port; | ||||
|   uint16_t source_port; | ||||
|   int udp_socket, num_ifaces; | ||||
|   int auto_detect = 1, i; | ||||
| 
 | ||||
|   /* parse config file */ | ||||
|   if (conf_devices[0] != NULL) | ||||
|     { | ||||
|       if (strcmp(conf_devices[0], "networking=no") == 0) | ||||
|         { | ||||
|           /* networking=no may only occur on the first non-commented line */ | ||||
|           DBG(LOG_DEBUG, "sanei_axis_find_devices: networking disabled in configuration file\n"); | ||||
|           return SANE_STATUS_GOOD; | ||||
|         } | ||||
|       for (i = 0; conf_devices[i] != NULL; i++) | ||||
|         { | ||||
| 	  if (!strcmp(conf_devices[i], "auto_detection=no")) | ||||
|             { | ||||
|               auto_detect = 0; | ||||
| 	      DBG(LOG_DEBUG, "sanei_axis_find_devices: auto detection of network scanners disabled in configuration file\n"); | ||||
| 	      continue; | ||||
| 	    } | ||||
| 	  else | ||||
|             { | ||||
|               DBG(LOG_DEBUG, "sanei_axis_find_devices: Adding scanner from pixma.conf: %s\n", conf_devices[i]); | ||||
|               strncpy(uri, conf_devices[i], sizeof(uri) - 1); | ||||
|               uri[sizeof(uri) - 1] = '\0'; | ||||
|               if (axis_no_devices >= AXIS_NO_DEVICES) | ||||
|                 { | ||||
|                   DBG(LOG_INFO, "sanei_axis_find_devices: device limit %d reached\n", AXIS_NO_DEVICES); | ||||
|                   return SANE_STATUS_NO_MEM; | ||||
|                 } | ||||
| 
 | ||||
|               struct sockaddr_in addr; | ||||
|               if (parse_uri(uri, &addr)) | ||||
|                 continue; | ||||
|               udp_socket = create_udp_socket(htonl(INADDR_ANY), &source_port); | ||||
|               if (udp_socket < 0) | ||||
|                 return SANE_STATUS_IO_ERROR; | ||||
|               if (get_device_name(udp_socket, addr.sin_addr.s_addr, AXIS_WIMP_PORT, devname, sizeof(devname)) == 0) | ||||
|                 { | ||||
|                   device[axis_no_devices++].addr = addr.sin_addr; | ||||
|                   attach_axis(uri, devname, inet_ntoa(addr.sin_addr), pixma_devices); | ||||
|                 } | ||||
|               close(udp_socket); | ||||
| 	    } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   if (!auto_detect) | ||||
|     return SANE_STATUS_GOOD; | ||||
| 
 | ||||
|   udp_socket = create_udp_socket(htonl(INADDR_ANY), &source_port); | ||||
|   if (udp_socket < 0) | ||||
|     return SANE_STATUS_IO_ERROR; | ||||
|   DBG(LOG_INFO, "source port=%d\n", source_port); | ||||
|   DBG(LOG_DEBUG, "source port=%d\n", source_port); | ||||
| 
 | ||||
|   /* send broadcast discover packets to all interfaces */ | ||||
|   num_ifaces = send_broadcasts(udp_socket, source_port); | ||||
|  | @ -450,21 +551,18 @@ sanei_axis_find_devices (const char **conf_devices, | |||
| //    struct axis_wimp_server_info *s_info = (void *)(packet + sizeof(struct axis_wimp_header));
 | ||||
| 
 | ||||
|     DBG(LOG_INFO, "got reply from %s\n", inet_ntoa(from.sin_addr)); | ||||
|     /* get remote port */ | ||||
|     remote_port = ntohs(from.sin_port); | ||||
|     DBG(LOG_INFO, "remote port=%d\n", remote_port); | ||||
|     if (header->type != (WIMP_SERVER_INFO | WIMP_REPLY)) { | ||||
|       DBG(LOG_NOTICE, "Received invalid reply\n"); | ||||
|       continue; | ||||
|     } | ||||
| 
 | ||||
|     get_device_name(udp_socket, from.sin_addr.s_addr, remote_port, devname, sizeof(devname)); | ||||
|     /* construct URI */ | ||||
|     sprintf (uri, "%s://%s:%d", "axis", inet_ntoa(from.sin_addr), AXIS_SCAN_PORT); | ||||
|     get_device_name(udp_socket, from.sin_addr.s_addr, ntohs(from.sin_port), devname, sizeof(devname)); | ||||
|     sprintf(uri, "axis://%s", inet_ntoa(from.sin_addr)); | ||||
| 
 | ||||
|     device[axis_no_devices++].addr = from.sin_addr; | ||||
|     attach_axis(uri, devname, inet_ntoa(from.sin_addr), pixma_devices); | ||||
|   } | ||||
|   close(udp_socket); | ||||
| 
 | ||||
|   return SANE_STATUS_GOOD; | ||||
| } | ||||
|  | @ -472,41 +570,16 @@ sanei_axis_find_devices (const char **conf_devices, | |||
| extern SANE_Status | ||||
| sanei_axis_open (SANE_String_Const devname, SANE_Int * dn) | ||||
| { | ||||
|   const char *uri_ip, *uri_port; | ||||
|   char ip[16]; | ||||
|   size_t ip_len; | ||||
|   int port = AXIS_SCAN_PORT; | ||||
|   struct in_addr addr; | ||||
|   int i; | ||||
|   char *username; | ||||
|   struct sockaddr_in address; | ||||
| 
 | ||||
|   DBG(LOG_INFO, "%s(%s, %d)\n", __func__, devname, *dn); | ||||
|   if (strncmp(devname, "axis://", 7)) { | ||||
|     DBG(LOG_CRIT, "Invalid protocol in devname"); | ||||
|   if (parse_uri(devname, &address)) | ||||
|     return SANE_STATUS_INVAL; | ||||
|   } | ||||
|   uri_ip = devname + 7; | ||||
| 
 | ||||
|   uri_port = strchr(uri_ip, ':'); | ||||
|   if (uri_port) { | ||||
|     sscanf(uri_port, ":%d", &port); | ||||
|     ip_len = uri_port - uri_ip; | ||||
|   } else | ||||
|     ip_len = strlen(uri_ip); | ||||
|   if (ip_len > sizeof(ip)) | ||||
|     ip_len = sizeof(ip); | ||||
|   strncpy(ip, uri_ip, ip_len); | ||||
|   ip[ip_len] = '\0'; | ||||
| 
 | ||||
|   if (inet_aton(ip, &addr) == 0) { | ||||
|     DBG(LOG_CRIT, "Invalid IP address in devname"); | ||||
|     return SANE_STATUS_INVAL; | ||||
|   } | ||||
|   DBG(LOG_INFO, "ip=%s, port=%d\n", inet_ntoa(addr), port); | ||||
| 
 | ||||
|   for (i = 0; i < axis_no_devices; i++) | ||||
|     if (device[i].addr.s_addr == addr.s_addr) { | ||||
|     if (device[i].addr.s_addr == address.sin_addr.s_addr) { | ||||
|       DBG(LOG_INFO, "found device at position %d\n", i); | ||||
|       *dn = i; | ||||
|       /* connect */ | ||||
|  | @ -515,10 +588,6 @@ sanei_axis_open (SANE_String_Const devname, SANE_Int * dn) | |||
|         perror("Unable to create TCP socket"); | ||||
|         return SANE_STATUS_IO_ERROR; | ||||
|       } | ||||
|       address.sin_family = AF_INET; | ||||
|       /* set TCP destination port and address */ | ||||
|       address.sin_port = htons(AXIS_SCAN_PORT); | ||||
|       address.sin_addr.s_addr = addr.s_addr; | ||||
|       if (connect(tcp_socket, (struct sockaddr *) &address, sizeof(address)) < 0) { | ||||
|         perror("Unable to connect"); | ||||
|         return SANE_STATUS_IO_ERROR; | ||||
|  | @ -542,7 +611,7 @@ sanei_axis_open (SANE_String_Const devname, SANE_Int * dn) | |||
| 
 | ||||
|       return SANE_STATUS_GOOD; | ||||
|     } | ||||
| /*FIXME: add to table */ | ||||
| 
 | ||||
|   return SANE_STATUS_INVAL; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Ondrej Zary
						Ondrej Zary