00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030 #include <ctype.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <getopt.h>
00035 #include <assert.h>
00036 #include <unistd.h>
00037 #include <stdarg.h>
00038
00039 #include <glib.h>
00040
00041 #include "../logger.h"
00042 #include "../device_store.h"
00043 #include "linux_class_v4l.h"
00044
00052
00053 static void visit_class_device_v4l_got_sysdevice(HalDevice* parent,
00054 void* data1, void* data2);
00055
00064 void visit_class_device_v4l(const char* path,
00065 struct sysfs_class_device* class_device)
00066 {
00067 HalDevice* d;
00068 struct sysfs_attribute* cur;
00069 char* sysdevice_sysfs_path;
00070 char* product_name = NULL;
00071 char attr_name[SYSFS_NAME_LEN];
00072 char v4l_class[32];
00073 const char* last_elem;
00074 int adapter_num;
00075 int len;
00076 int i;
00077 char buf[256];
00078 char dev_file[256];
00079
00080 if( class_device->sysdevice==NULL )
00081 {
00082 HAL_INFO(("Skipping virtual class device at path %s\n", path));
00083 return;
00084 }
00085
00086 HAL_INFO(("v4l: sysdevice_path=%s, path=%s\n", class_device->sysdevice->path, path));
00087
00090
00091 last_elem = get_last_element(path);
00092 sscanf(last_elem, "%32[a-z]%d", v4l_class, &adapter_num);
00093
00094
00095 dlist_for_each_data(sysfs_get_classdev_attributes(class_device), cur,
00096 struct sysfs_attribute)
00097 {
00098 if( sysfs_get_name_from_path(cur->path,
00099 attr_name, SYSFS_NAME_LEN) != 0 )
00100 continue;
00101
00102
00103 len = strlen(cur->value);
00104 for(i=len-1; isspace(cur->value[i]); --i)
00105 cur->value[i] = '\0';
00106
00107
00108
00109 if( strcmp(attr_name, "name")==0 )
00110 product_name = cur->value;
00111 }
00112
00113
00114
00115 dev_file[0] = '\0';
00116 if( is_probing )
00117 {
00118 int i;
00119 int sysfs_mount_path_len;
00120 char sysfs_path_trunc[SYSFS_NAME_LEN];
00121 char* udev_argv[7] = {"/sbin/udev", "-r", "-q", "name", "-p",
00122 sysfs_path_trunc, NULL};
00123 char* udev_stdout;
00124 char* udev_stderr;
00125 int udev_exitcode;
00126
00127
00128 sysfs_mount_path_len = strlen(sysfs_mount_path);
00129 if( strlen(path)>sysfs_mount_path_len )
00130 {
00131 strncpy(sysfs_path_trunc, path + sysfs_mount_path_len,
00132 SYSFS_NAME_LEN);
00133 }
00134 HAL_INFO(("*** sysfs_path_trunc = '%s'", sysfs_path_trunc));
00135
00136
00137 if( g_spawn_sync("/",
00138 udev_argv,
00139 NULL,
00140 0,
00141 NULL,
00142 NULL,
00143 &udev_stdout,
00144 &udev_stderr,
00145 &udev_exitcode,
00146 NULL)!=TRUE )
00147 {
00148 HAL_ERROR(("Couldn't invoke /sbin/udev"));
00149 goto error;
00150 }
00151
00152 if( udev_exitcode!=0 )
00153 {
00154 HAL_ERROR(("/sbin/udev returned %d", udev_exitcode));
00155 goto error;
00156 }
00157
00158
00159 for(i=0; udev_stdout[i]!=0; i++)
00160 {
00161 if( udev_stdout[i]=='\r' || udev_stdout[i]=='\n' )
00162 {
00163 udev_stdout[i]=0;
00164 break;
00165 }
00166 }
00167
00168 strncat(dev_file, udev_stdout, 256);
00169
00171 }
00172 else
00173 {
00174 error:
00175 }
00176
00177 HAL_INFO(("device file = '%s'", dev_file));
00178
00179 d = ds_device_new();
00180 ds_add_capability(d, "v4l");
00181 ds_property_set_string(d, "info.category", "v4l");
00182 if( strcmp(v4l_class, "vbi")==0 )
00183 {
00184 ds_property_set_string(d, "v4l.vbi.linux.sysfs_path", path);
00185 ds_property_set_int(d, "v4l.vbi.adapter", adapter_num);
00186 ds_property_set_string(d, "v4l.vbi.device", dev_file);
00187
00188 if ( product_name==NULL )
00189 ds_property_set_string(d, "v4l.vbi.name", "V4L vbi");
00190 else
00191 ds_property_set_string(d, "v4l.vbi.name", product_name);
00192
00193 ds_add_capability(d, "v4l.vbi");
00194 }
00195 else if( strcmp(v4l_class, "video")==0 )
00196 {
00197 ds_property_set_string(d, "v4l.video.linux.sysfs_path", path);
00198 ds_property_set_int(d, "v4l.video.adapter", adapter_num);
00199 ds_property_set_string(d, "v4l.video.device", dev_file);
00200
00201 if ( product_name==NULL )
00202 ds_property_set_string(d, "v4l.video.name", "V4L video");
00203 else
00204 ds_property_set_string(d, "v4l.video.name", product_name);
00205
00206 ds_add_capability(d, "v4l.video");
00207 }
00208 else if( strcmp(v4l_class, "radio")==0 )
00209 {
00210 ds_property_set_string(d, "v4l.radio.linux.sysfs_path", path);
00211 ds_property_set_int(d, "v4l.radio.adapter", adapter_num);
00212 ds_property_set_string(d, "v4l.radio.device", dev_file);
00213
00214 if ( product_name==NULL )
00215 ds_property_set_string(d, "v4l.radio.name", "V4L radio");
00216 else
00217 ds_property_set_string(d, "v4l.radio.name", product_name);
00218
00219 ds_add_capability(d, "v4l.radio");
00220 }
00221
00222 sysdevice_sysfs_path = class_device->sysdevice->path;
00223
00224
00225
00226
00227
00228 ds_device_async_find_by_key_value_string(
00229 "linux.sysfs_path_device",
00230 sysdevice_sysfs_path,
00231 TRUE,
00232 visit_class_device_v4l_got_sysdevice,
00233 (void*) d, NULL,
00234 is_probing ? 0 :
00235 HAL_LINUX_HOTPLUG_TIMEOUT);
00236
00237 free(sysdevice_sysfs_path);
00238 }
00239
00247 static void visit_class_device_v4l_got_sysdevice(HalDevice* sysdevice,
00248 void* data1, void* data2)
00249 {
00250 HalDevice* d = (HalDevice*) data1;
00251
00252
00253
00254 if( sysdevice==NULL )
00255 {
00256 HAL_ERROR(("No sysdevice for V4L device!"));
00257 ds_device_destroy(d);
00258 return;
00259 }
00260 else
00261 {
00262 ds_device_merge(sysdevice, d);
00263 }
00264
00265 ds_device_destroy(d);
00266 }
00267
00271 void linux_class_v4l_init()
00272 {
00273 }
00274
00279 void linux_class_v4l_detection_done()
00280 {
00281 }
00282
00286 void linux_class_v4l_shutdown()
00287 {
00288 }
00289