00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <unistd.h>
00005 #include <fcntl.h>
00006 #include <sys/stat.h>
00007 #include <sys/ioctl.h>
00008 #include <sys/mman.h>
00009
00010
00011 #include <asm/elphel/autoexp.h>
00012 #include <asm/elphel/c313a.h>
00013
00014
00015 #define AE_DEVICE AUTOEXP_DEV_NAME
00016 #define QRY_MAXPARAMS 64
00017
00018 char copyQuery [4096];
00019 const char *uri;
00020 const char *method;
00021 const char *query;
00022 int driver;
00023 struct autoexp_t aestate;
00024 int erroroper;
00025
00026 struct key_value {
00027 char *key;
00028 char *value;
00029 };
00030
00031 struct key_value gparams[QRY_MAXPARAMS+1];
00032
00033 int unescape(char *, int);
00034 int hexdigit(char);
00035 char * paramValue(struct key_value *, char *);
00036 int parseQuery(struct key_value *, char *);
00037 void makeXML(void);
00038 void setAEParams(void);
00039 void getAEParams(void);
00040 void fillAEStruct(void);
00041
00042 int i_val = -1;
00043 static unsigned long rval = 0;
00044 static unsigned long gval = 0;
00045 static unsigned long bval = 0;
00046 static unsigned long rval_or = 0;
00047 static unsigned long gval_or = 0;
00048 static unsigned long bval_or = 0;
00049 int i_perc = -1;
00050 static unsigned long rperc = 0;
00051 static unsigned long gperc = 0;
00052 static unsigned long bperc = 0;
00053 static unsigned long rperc_or = 0;
00054 static unsigned long gperc_or = 0;
00055 static unsigned long bperc_or = 0;
00056 static unsigned long rall = 0;
00057 static unsigned long gall = 0;
00058 static unsigned long ball = 0;
00059
00060 static struct autoexp_log_t ae_log_b[LOG_C];
00061 static int ae_log_c = 0;
00062
00063 int main (int argc, char *argv[]) {
00064 int i;
00065 struct stat buf;
00066 void *_map;
00067 char *_index;
00068 unsigned long *_h;
00069 unsigned short *_g;
00070
00071 char * _query = 0;
00072
00073 method = getenv("REQUEST_METHOD");
00074 _query = getenv("QUERY_STRING");
00075 uri = getenv("REQUEST_URI");
00076
00077 i = (_query) ? strlen (_query) : 0;
00078
00079
00080 if(i > (sizeof(copyQuery) - 1))
00081 i = sizeof(copyQuery) - 1;
00082 if(i > 0)
00083 strncpy(copyQuery, _query, i);
00084 copyQuery[i] = 0;
00085 unescape(copyQuery, sizeof(copyQuery));
00086
00087 if(method == NULL) {
00088
00089 printf("This program should be run as a CGI from the web server!\n");
00090 exit(1);
00091 }
00092
00093 parseQuery(gparams, copyQuery);
00094 fillAEStruct();
00095 if(stat(AE_DEVICE, &buf) == -1)
00096 driver = -1;
00097 else {
00098 driver = open(AE_DEVICE, O_RDWR);
00099 if(driver) {
00100 if(atoi(paramValue(gparams, "reg")) == 1)
00101 setAEParams();
00102 else
00103 getAEParams();
00104
00105 if((_index = paramValue(gparams, "ival")) != NULL) {
00106 i_val = atoi(_index);
00107 if(i_val < 0)
00108 i_val = 0;
00109 if(i_val > 255)
00110 i_val = 255;
00111 }
00112 if((_index = paramValue(gparams, "iperc")) != NULL) {
00113 i_perc = atoi(_index);
00114 if(i_perc < 0)
00115 i_perc = 0;
00116 if(i_perc > 255)
00117 i_perc = 255;
00118 }
00119 if((_index = paramValue(gparams, "log")) != NULL) {
00120 ae_log_c = atoi(_index);
00121 if(ae_log_c > 0) {
00122 if(ae_log_c > LOG_C)
00123 ae_log_c = LOG_C;
00124 if((ae_log_c = ioctl(driver, _IO(IOC_AUTOEXP_GET_LOG, ae_log_c & 0xFF), (void *)&ae_log_b)) < 0)
00125 ae_log_c = -1;
00126 } else {
00127 ae_log_c = 0;
00128 }
00129 }
00130 if(_query != 0) {
00131 if((_map = mmap(NULL, TABLES_LEN, PROT_READ, MAP_FIXED | MAP_SHARED, driver, 0)) != MAP_FAILED) {
00132 _h = (unsigned long *)_map;
00133 _g = (unsigned short *)(_map + 256 * 4 * 4 + 256 * 4 * 2 + 256 * 2);
00134 if(i_val != -1) {
00135 rval = _h[i_val];
00136 gval = _h[i_val + 256] + _h[i_val + 512];
00137 gval /= 2;
00138 bval = _h[i_val + 768];
00139 i_val = _g[i_val] >> 8;
00140 rval_or = _h[i_val];
00141 gval_or = _h[i_val + 256] + _h[i_val + 512];
00142 gval_or /= 2;
00143 bval_or = _h[i_val + 768];
00144 }
00145 if(i_perc != -1) {
00146 for(i = 0; i < 256; i++) {
00147 rall += _h[i];
00148 gall += _h[i + 256] + _h[i + 512];
00149 ball += _h[i + 768];
00150 if(i <= i_perc) {
00151 rperc += _h[i];
00152 gperc += _h[i + 256] + _h[i + 512];
00153 bperc += _h[i + 768];
00154 }
00155 }
00156 gperc /= 2;
00157 gall /= 2;
00158 i_perc = _g[i_perc] >> 8;
00159 for(i = 0; i <= i_perc; i++) {
00160 rperc_or += _h[i];
00161 gperc_or += _h[i + 256] + _h[i + 512];
00162 bperc_or += _h[i + 768];
00163 }
00164 gperc_or /= 2;
00165 }
00166 munmap(_map, TABLES_LEN);
00167 }
00168
00169 }
00170
00171 close(driver);
00172 }
00173 }
00174 makeXML();
00175
00176
00177 return 0;
00178 }
00179
00180 int unescape (char * s, int l) {
00181 int i=0;
00182 int j=0;
00183 while ((i<l) && s[i]) {
00184 if ((s[i]=='%') && (i<(l-2)) && s[i+1]){
00185 s[j++]=(hexdigit(s[i+1])<<4) | hexdigit(s[i+2]);
00186 i+=3;
00187 } else s[j++]=s[i++];
00188 }
00189 if (i<l) s[j]=0;
00190 return j;
00191 }
00192
00193 int hexdigit (char c) {
00194 int i;
00195 i=c-'0';
00196 if ((i>=0) && (i<10)) return i;
00197 i=c-'a'+10;
00198 if ((i>=10) && (i<16)) return i;
00199 i=c-'A'+10;
00200 if ((i>=10) && (i<16)) return i;
00201 return 0;
00202 }
00203
00204 char * paramValue(struct key_value * params, char * skey) {
00205 int i=0;
00206 if (skey)
00207 while ((i<QRY_MAXPARAMS) && (params[i].key)) {
00208 if (strcmp(skey,params[i].key)==0) return params[i].value;
00209
00210 i++;
00211 }
00212 return NULL;
00213 }
00214
00215 int parseQuery(struct key_value * params, char * qry) {
00216 char * cp;
00217 int l=0;
00218 cp=strtok(qry,"=");
00219 while ((cp) && (l<QRY_MAXPARAMS)) {
00220 params[l].key=cp;
00221 cp=strtok(NULL,"&");
00222 params[l++].value=cp;
00223 if (cp) cp=strtok(NULL,"=");
00224 }
00225 params[l].key=NULL;
00226 return l;
00227 }
00228
00229 void makeXML() {
00230 int i;
00231
00232 printf("%s","Content-Type: text/xml\n");
00233 printf("%s","Pragma: no-cache\n\n");
00234 printf("%s\n", "<?xml version='1.0' encoding='ISO8859-1'?>");
00235 printf("%s\n", "<AUTOEXPOSURESETTINGS>");
00236 printf("\t<DRIVERPRESENT>%i</DRIVERPRESENT>\n", (driver==-1 ? 0 : 1));
00237 printf("\t<ERROR>%i</ERROR>\n", (erroroper==-1 ? 1 : 0));
00238 printf("\t<AEONOFF>%li</AEONOFF>\n", aestate.on);
00239 printf("\t<WIDTH>%li</WIDTH>\n", aestate.width);
00240 printf("\t<HEIGHT>%li</HEIGHT>\n", aestate.height);
00241 printf("\t<LEFT>%li</LEFT>\n", aestate.left);
00242 printf("\t<TOP>%li</TOP>\n", aestate.top);
00243 printf("\t<EXPMAX>%li</EXPMAX>\n", aestate.exp_max);
00244 printf("\t<EXPOSURE>%li</EXPOSURE>\n", aestate.exp);
00245 printf("\t<OVEREXPMAX>%li</OVEREXPMAX>\n", aestate.overexp_max);
00246 printf("\t<SKIP_PMIN>%.2f</SKIP_PMIN>\n", ((float)aestate.skip_pmin) / 100.0);
00247 printf("\t<SKIP_PMAX>%.2f</SKIP_PMAX>\n", ((float)aestate.skip_pmax) / 100.0);
00248 printf("\t<SKIP_T>%.1f</SKIP_T>\n", ((float)aestate.skip_t) / 10.0);
00249
00250 printf("\t<OVEREXP>%li</OVEREXP>\n", 0L);
00251 if(i_val != -1) {
00252 printf("\t<RVAL>%lu</RVAL>\n", rval);
00253 printf("\t<GVAL>%lu</GVAL>\n", gval);
00254 printf("\t<BVAL>%lu</BVAL>\n", bval);
00255 printf("\t<RVAL_OR>%lu</RVAL_OR>\n", rval_or);
00256 printf("\t<GVAL_OR>%lu</GVAL_OR>\n", gval_or);
00257 printf("\t<BVAL_OR>%lu</BVAL_OR>\n", bval_or);
00258 }
00259 if(i_perc != -1) {
00260 printf("\t<RPERC>%.2f</RPERC>\n", ((double)rperc * 100) / rall);
00261 printf("\t<GPERC>%.2f</GPERC>\n", ((double)gperc * 100) / gall);
00262 printf("\t<BPERC>%.2f</BPERC>\n", ((double)bperc * 100) / ball);
00263 printf("\t<RPERC_OR>%.2f</RPERC_OR>\n", ((double)rperc_or * 100) / rall);
00264 printf("\t<GPERC_OR>%.2f</GPERC_OR>\n", ((double)gperc_or * 100) / gall);
00265 printf("\t<BPERC_OR>%.2f</BPERC_OR>\n", ((double)bperc_or * 100) / ball);
00266 }
00267 printf("\t<PERCENT>%.2f</PERCENT>\n", ((double)aestate.s_percent) / 100.0);
00268 printf("\t<INDEX>%lu</INDEX>\n", aestate.s_index);
00269 if(ae_log_c > 0) {
00270 for(i = 0; i < ae_log_c; i++) {
00271 printf("\t<LOG>time == %ld:%ld; t_value == %.1f; t_scale == %.2f; n_index == %ld; n_percent == %.2f, s_index == %ld, s_percent == %.2f</LOG>",
00272 ae_log_b[i].tv_sec, ae_log_b[i].tv_usec,
00273 ((float)ae_log_b[i].t_value) / 10.0, ((float)ae_log_b[i].t_scale / 0x10000),
00274 ae_log_b[i].n_index, ((float)ae_log_b[i].n_percent) / 100.0,
00275 ae_log_b[i].s_index, ((float)ae_log_b[i].s_percent) / 100.0);
00276 }
00277 }
00278 if(ae_log_c == -1)
00279 printf("\t<LOG>can't read log</LOG>\n");
00280 printf("%s\n", "</AUTOEXPOSURESETTINGS>");
00281 }
00282
00283 void fillAEStruct() {
00284 char *prm;
00285
00286 if((prm = paramValue(gparams, "onoff")) != NULL) {
00287 aestate.on = atol(prm);
00288 if(aestate.on != 1)
00289 aestate.on = 0;
00290 }
00291 else
00292 aestate.on = HIST_NOT_CHANGE;
00293
00294 if((prm = paramValue(gparams, "width")) != NULL) {
00295 aestate.width = atol(prm);
00296 if(aestate.width < 5)
00297 aestate.width = 5;
00298 if(aestate.width > 100)
00299 aestate.width = 100;
00300 }
00301 else
00302 aestate.width = HIST_NOT_CHANGE;
00303
00304
00305 if((prm = paramValue(gparams, "height")) != NULL) {
00306 aestate.height = atol(prm);
00307 if(aestate.height < 5)
00308 aestate.height = 5;
00309 if(aestate.height > 100)
00310 aestate.height = 100;
00311 }
00312 else
00313 aestate.height = HIST_NOT_CHANGE;
00314
00315
00316 if((prm = paramValue(gparams, "left")) != NULL) {
00317 aestate.left = atol(prm);
00318 if(aestate.left < 0)
00319 aestate.left = 0;
00320 if(aestate.left > 100)
00321 aestate.left = 100;
00322 }
00323 else
00324 aestate.left = HIST_NOT_CHANGE;
00325
00326
00327
00328 if((prm = paramValue(gparams, "top")) != NULL) {
00329 aestate.top = atol(prm);
00330 if(aestate.top < 0)
00331 aestate.top = 0;
00332 if(aestate.top > 100)
00333 aestate.top = 100;
00334 }
00335 else
00336 aestate.top = HIST_NOT_CHANGE;
00337
00338
00339
00340 if((prm = paramValue(gparams, "expmax")) != NULL) {
00341 aestate.exp_max = atol(prm);
00342 if(aestate.exp_max < 20)
00343 aestate.exp_max = 20;
00344 if(aestate.exp_max > 100000)
00345 aestate.exp_max = 100000;
00346 }
00347 else
00348 aestate.exp_max = HIST_NOT_CHANGE;
00349
00350
00351
00352 if((prm = paramValue(gparams, "oemax")) != NULL) {
00353 aestate.overexp_max = atol(prm);
00354 if(aestate.overexp_max < 1)
00355 aestate.overexp_max = 10;
00356 if(aestate.overexp_max > 2500)
00357 aestate.overexp_max = 2500;
00358 }
00359 else
00360 aestate.overexp_max = HIST_NOT_CHANGE;
00361
00362 if((prm = paramValue(gparams, "percent")) != NULL) {
00363 aestate.s_percent = atof(prm) * 100;
00364 if(aestate.s_percent < 0)
00365 aestate.s_percent = 0;
00366 if(aestate.s_percent > 10000)
00367 aestate.s_percent = 10000;
00368 }
00369 else
00370 aestate.s_percent = HIST_NOT_CHANGE;
00371
00372 if((prm = paramValue(gparams, "index")) != NULL) {
00373 aestate.s_index = atol(prm);
00374 if(aestate.s_index < 0)
00375 aestate.s_index = 0;
00376 if(aestate.s_index > 255)
00377 aestate.s_index = 255;
00378 }
00379 else
00380 aestate.s_index = HIST_NOT_CHANGE;
00381
00382 if((prm = paramValue(gparams, "skip_pmin")) != NULL) {
00383 aestate.skip_pmin = atof(prm) * 100;
00384 if(aestate.skip_pmin < 0)
00385 aestate.skip_pmin = 1;
00386 if(aestate.skip_pmin > 1000)
00387 aestate.skip_pmin = 1000;
00388 }
00389 else
00390 aestate.skip_pmin = HIST_NOT_CHANGE;
00391 if((prm = paramValue(gparams, "skip_pmax")) != NULL) {
00392 aestate.skip_pmax = atof(prm) * 100;
00393 if(aestate.skip_pmax < 4000)
00394 aestate.skip_pmax = 4000;
00395 if(aestate.skip_pmax > 9000)
00396 aestate.skip_pmax = 9000;
00397 }
00398 else
00399 aestate.skip_pmax = HIST_NOT_CHANGE;
00400 if((prm = paramValue(gparams, "skip_t")) != NULL) {
00401 aestate.skip_t = atof(prm) * 10;
00402 if(aestate.skip_t < 0)
00403 aestate.skip_t = 0;
00404 if(aestate.skip_t > 50)
00405 aestate.skip_t = 50;
00406 }
00407 else
00408 aestate.skip_t = HIST_NOT_CHANGE;
00409 }
00410
00411 void setAEParams() {
00412 getAEParams();
00413 fillAEStruct();
00414 erroroper=ioctl(driver, _IO(IOC_AUTOEXP_SET, 0x00), &aestate);
00415 }
00416
00417 void getAEParams() { erroroper=ioctl(driver, _IO(IOC_AUTOEXP_GET, 0x00), &aestate); }