int main(int argc, char **argv) { if (initiate(argv[0]) == -1) return -1; if (connect_2_analyze_server(&analyze_fd) == -1) analyze_broken = 1; else analyze_broken = 0; connect_2_backup_server(&backup_fd); store_result_t result; while( FCGI_Accept() >= 0) { //用cgic初始化获取post数据 cgic_initiate(0, 0); FCGI_printf("Content-type:image/gif\r\n\r\n"); //判断数据合法性,如合法则放入result中 if( prepare_data(&result) == -1) goto continue_tag; //先发到缓存 if (backup_fd == -1) connect_2_backup_server(&backup_fd);//重新连接 if (backup_fd != -1) send_2_server(&result, &backup_fd, "backup", analyze_broken); //将数据发送出去 if (analyze_fd == -1) { if (connect_2_analyze_server(&analyze_fd) == -1)//重新连接 analyze_broken = 1; else analyze_broken = 0; } if(analyze_fd != -1) send_2_server(&result, &analyze_fd, "analyze", 0); continue_tag: //释放cgic中取数据所分配的内存 cgiFreeResources(); FCGI_Finish(); } close(analyze_fd); close(backup_fd); destroy(); return 1; }
/* * @brief 处理当前目录下所有标记为N的文件 * @param DIR *dir:目录指针; char *folder:目录名; char *file:当前文件名 * @return 0表示处理成功且有新文件,可继续处理; -1表示处理失败,或处理成功但没有新文件,可休眠。 */ int processdir(DIR *dir) { struct dirent *ptr; int retv; char fullpath[FULL_PATH_LEN]; while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0]=='N') { snprintf(fullpath, FULL_PATH_LEN, "%s/%s", data_store_path, ptr->d_name); get_time_string(); retv = send_2_server(fullpath); if (retv >= 0) { //ret =0 ok! 1 bad files remove(fullpath); } else { //ret -1, can't send file, then return and have a rest return -1; } }//if }//while return 0; }
/* * @brief 处理当前目录下所有标记为N的文件 * @param DIR *dir:目录指针; char *folder:目录名; char *file:当前文件名 * @return 0表示处理成功且有新文件,可继续处理; -1表示处理失败,或处理成功但没有新文件,可休眠。 */ int processdir(DIR *dir, const char *folder, const char *file) { struct dirent *ptr; file_t *mylink = NULL; file_t *tmp = NULL; file_t *fnext = NULL; file_t *pos = NULL; char current_largest[FILE_NAME_LEN]; char lastfile[FILE_NAME_LEN]; snprintf(lastfile, FILE_NAME_LEN, "N%04d.%s-23-59", machine_number, folder); if (strcmp(file,lastfile) >= 0) { write_log("%s have already processed last time!\n", folder); return 0; //this dir was processed last time; } snprintf(current_largest, FILE_NAME_LEN, "%s", file); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0]=='N' && strcmp(ptr->d_name,lastfile) <= 0) { if (strcmp(ptr->d_name, current_largest) > 0) strncpy(current_largest, ptr->d_name, FILE_NAME_LEN); if ((tmp = (file_t*)malloc(sizeof(file_t))) == NULL) { write_log("Process dir:malloc failed!\n"); closedir(dir); pthread_exit(NULL); } snprintf(tmp->filename, FILE_NAME_LEN, "%s", ptr->d_name); snprintf(tmp->fullpath, FULL_PATH_LEN, "%s/%s/%s", data_store_path, folder, ptr->d_name); tmp->next = NULL; //insert sort; if (mylink == NULL) mylink = tmp; else { fnext = mylink; while (fnext != NULL) { if (strcmp(tmp->filename, fnext->filename) > 0) { pos = fnext;//暂存插入点的前一点 fnext = fnext->next; } else break; } if (fnext == mylink) { tmp->next = mylink; mylink = tmp; } else if (fnext == NULL) pos->next = tmp; else { pos->next = tmp; tmp->next = fnext; } }//insert sort }//if }//while //process file in link; tmp = mylink; int retv; while (tmp != NULL) { retv = send_2_server(tmp->fullpath); if (retv == 0) { //ret =0 ok! update files and change file's name update_file(tmp->filename); char str[FULL_PATH_LEN]; tmp->filename[0] = 'Y'; snprintf(str, FULL_PATH_LEN, "%s/%s/%s", data_store_path, folder, tmp->filename); rename(tmp->fullpath, str); } else if (retv == 1) { //ret 1 , bad files,ignore just update files update_file(tmp->filename); //add by tonyliu 2012-11-09 //rename bad file name from N0006.2012-11-09-04-55 to E0006.2012-11-09-04-55 char str[FULL_PATH_LEN]; tmp->filename[0] = 'E'; snprintf(str, FULL_PATH_LEN, "%s/%s/%s", data_store_path, folder, tmp->filename); rename(tmp->fullpath, str); } else { //ret -1, can't send file, then return and have a rest // but you have to free memory first when reading dir // so just break and free memory down near by and test ret again break; } tmp = tmp->next; } //free memory tmp = mylink; while (mylink != NULL) { tmp = mylink; mylink = mylink->next; free(tmp); } if ( retv == -1) return -1;//ret== -1表示没有发送成功,则返回并休眠,下次再尝试发送 if (strcmp(current_largest, lastfile) >= 0) { write_log("Good %s processed perfectly!!!\n", folder); return 0;//file complete then ok } else if (update_folder(folder, TEST_FOLDER_EXISTENCE) == 0) { //file in this folder not complete but next folder exist,then process next folder //memcpy(tmpfolder, foldername, FOLDER_NAME_LEN); return 0; } else { //file not complete and next folder does not exist then wait few seconds //memcpy(tmpfolder, foldername, FOLDER_NAME_LEN);//roll back change about tmpfolder int times = 1; while (times <= 5) {//test five times for coming new files rewinddir(dir); while ((ptr = readdir(dir)) != NULL) { if ( ptr->d_name[0] == 'N' && strcmp(ptr->d_name,current_largest) > 0 && strcmp(ptr->d_name,lastfile) <= 0) { strncpy(current_largest, ptr->d_name, FILE_NAME_LEN); char buffer[FULL_PATH_LEN]; snprintf(buffer, FULL_PATH_LEN, "%s/%s/%s",data_store_path,folder,ptr->d_name); int retv; retv = send_2_server(buffer); if (retv == 0) { //ret =0,1 ok! update files and change file's name update_file(current_largest); char str[FULL_PATH_LEN]; //current_largest[0]='Y';//不能改,否则影响后续循环 snprintf(str, FULL_PATH_LEN, "%s/%s/Y%s", data_store_path, folder, ¤t_largest[1]); rename(buffer, str); write_log("IN TEST FIVE: %s", str);//for debug } else if (retv == 1) { //ret == 1 bad files,ignore, just update files update_file(current_largest); //add by tonyliu 2012-11-09 //rename bad file name from N0006.2012-11-09-04-55 to E0006.2012-11-09-04-55 char str[FULL_PATH_LEN]; snprintf(str, FULL_PATH_LEN, "%s/%s/E%s", data_store_path, folder, ¤t_largest[1]); rename(buffer, str); write_log("IN TEST FIVE: %s", str);//for debug } else { //ret -1, can't send file, then return and have a rest // but you have to free memory first when reading dir // so just break and free memory down near by and test ret again break; } times=0;//have new file } } times++; }//while }//else return -1;//you can have a rest }
/* ******************************************************************** * MAIN PROGRAM * * We use HIGE timers in order to see system performance with vmstat * * ******************************************************************** */ int main(int argc, char **argv) { int i,c; int errflg = 0; int iflg = 0; int wflg = 0; // WIringPI int repeats = 1; // We can repeat readings int attempts = 0; // How many attempts were necessary to be successful int fake = 0; extern char *optarg; extern int optind, optopt; mode = SOCK_STREAM; // default Socket mode // ------------------------- COMMANDLINE OPTIONS SETTING ---------------------- // Valid options are: // -h <hostname> ; hostname or IP address of the daemon // -p <port> ; Portnumber for daemon socket // -b ; Broadcast mode // -v ; Verbose, Give detailed messages // -w ; WiringPi mode // while ((c = getopt(argc, argv, ":bc:dfh:ip:r:stvw")) != -1) { switch(c) { case 'b': mode = SOCK_DGRAM; // UDP Datagram Mode, broadcastoing break; case 'c': cflg = 1; // Checks checks = atoi(optarg); break; case 'd': // Daemon mode, cannot be together with test? dflg = 1; break; case 'f': fake = 1; break; case 'h': // Socket communication dflg++; // Need daemon flag too, (implied) hostname = optarg; break; case 'i': // Interrupt (instead of waiting out). iflg=1; if (wflg) errflg++; break; case 'p': // Port number port = optarg; dflg++; // Need daemon flag too, (implied) break; case 'r': // repeats repeats = atoi(optarg); break; case 's': // Statistics sflg = 1; break; case 't': // Test Mode, do debugging debug=1; break; case 'v': // Verbose, output long timing/bit strings verbose = 1; break; case 'w': // wiringpi library used wflg = 1; if (iflg) errflg++; break; case ':': // -f or -o without operand fprintf(stderr,"Option -%c requires an operand\n", optopt); errflg++; break; case '?': fprintf(stderr, "Unrecognized option: -%c\n", optopt); errflg++; } } // -------------------- PRINT ERROR --------------------------------------- // Print error message if parsing the commandline // was not successful if (errflg) { fprintf(stderr, "usage: argv[0] (options) \n\n"); fprintf(stderr, "-b\t\t; Broadcast mode. Use UDP broadcasting\n"); fprintf(stderr, "-d\t\t; Daemon mode. Codes received will be sent to another host at port 5000\n"); fprintf(stderr, "-i\t\t; Interrupt based sensor processing\n"); fprintf(stderr, "-w\t\t; WiringPI libs used for sensor processing\n"); fprintf(stderr, "-s\t\t; Statistics, will gather statistics from remote\n"); fprintf(stderr, "-r\t\t; Repeats, will gather statistics #repeats times\n"); fprintf(stderr, "-t\t\t; Test mode, will output received code from remote\n"); fprintf(stderr, "-v\t\t; Verbose, will output more information about the received codes\n"); exit (2); } // ------------------ SETUP WIRINGPI -------------------------------------------- // Now start with setup wiringPI // wiringPiSetup(); // ------------------ PRINTING Parameters ------------------------------ // if (verbose == 1) { printf("The following options have been set:\n\n"); printf("-v\t; Verbose option\n"); if (statistics>0) printf("-s\t; Statistics option\n"); if (dflg>0) printf("-d\t; Daemon option\n"); if (iflg>0) printf("-i\t; Interrupt processing\n"); if (wflg>0) printf("-w\t; WIringPI library processing\n"); if (debug) printf("-t\t; Test and Debug option\n"); if (repeats>=1) printf("-r\t; Repeats: %d\n",repeats); if (mode != SOCK_STREAM) printf("-b\t; UDP Broadcasting option\n"); printf("\n"); }//if verbose // If we are in daemon mode, initialize sockets etc. // if (dflg) { daemon_mode(hostname, port, mode); } if (sflg) { fprintf(stderr,"init statistics\n"); init_statistics(statistics); // Make cells 0 } // ------------------------ // MAIN LOOP // delay(500); // Wait 2 secs before starting // We will initialize the interrupt handler to only react to a falling edge. // SO as every bit consists of a high pulse of 50 and a low pulse of either 28 or 75 usec // when we measure the falling edge only a 50+28 means a 0 and a 50+75usec flank means 1 // if (iflg) { wiringPiISR (DHT22PIN, INT_EDGE_FALLING, &sensor_interrupt); } for (i=0; i<repeats; i++) { if (iflg) { // Use an interrupt routing, less resource consuming attempts = dht22_read_int(i); } else if (wflg) { // Make use of the special library for these devices in wiringPI attempts = dht22_read_wiring(i); } else if (fake) { attempts = 1; send_2_server(sockfd, 50, 10); } else { // Use the brute force method and wait all reads out attempts = dht22_read_old(i); } if (attempts <= 100) { printf(" It took %d attempts to read\n",attempts); } else { printf(" dht22: Unable to read a value in 100 attempts\n"); } delay(2000); // wait 2.0 secs } // Close the socket to the daemon if (close(sockfd) == -1) { perror("Error closing socket to daemon"); } exit(EXIT_SUCCESS); }
/* ********************************************************************************* * dht22_read_int * * Read function based on interrupt processing * argument r describes the repeat index number (meaningful if we have large * numbers of repeats. * This -i option seems to take less time to come to results, however its system time * to reach that result is higher than the original (brute force) timer result. ********************************************************************************* */ int dht22_read_int(int r) { uint8_t j,i; uint8_t linex; int time_interval = 0; int attempts = 0; int result = 0; // We want at least ONE successful read of the sensor values. while ((result == 0) && (attempts++ < 100)) { j=0; stop_ints = 1; // Disable interrupts for the moment time_interval = 0; delay(50); // XXX Necessary? pullUpDnControl (DHT22PIN, PUD_UP); // Start with a HIGH value digitalWrite(DHT22PIN,HIGH); delay(5); // Wait a little, 5 millisec for(i=0; i<5; i++) dht22_val[i]=0; // Initialize result to 0 // Send the request pulse // pinMode(DHT22PIN,OUTPUT); digitalWrite(DHT22PIN,LOW); delay(24); // Wait 18 milli seconds digitalWrite(DHT22PIN,HIGH); delayMicroseconds(18); // Pull up 20-40 uSec // Switch to input mode, enable interrupts // Set pin mode to input pinMode(DHT22PIN,INPUT); piHiPri (10); // Give this program higher interrupt than std stop_ints = 0; //pullUpDnControl (DHT22PIN, PUD_UP); // Set data to a HIGH value // Receive bits, wait for interrupts to finish // start_time = micros(); p_index = 0; // Initialize index edgeTimeStamp[1] = start_time; while (1) { delayMicroseconds(5); time_interval = micros() - start_time; if ( time_interval > 12000 ) // 40 bits * (50+75) usec max = 6000 usec { if (debug) printf("\n\nERROR: Timeout, p_index: %d, interval: %d uSec\n", p_index, time_interval); break; } if ( p_index > 41 ) { if (debug) printf("\n\nERROR: p_index overflow, p_index: %d, interval: %d uSec\n", p_index, time_interval); break; } } start_time = 0; // Reset timer piHiPri (0); linex=0; if (verbose) printf("Printing values, %d found:\n", p_index); for (i=0; i< p_index; i++) { // useless transitions are ignored. But the difference between 0 and 1 is not just the // typical value of 28uSec or 70uSec. This is because the system itself takes time as well to evaluate // transitions if (i>=1) { dht22_val[j/8]<<=1; // Shift one bit to left if (pulse_array[i] > 110) // "0"=50+28 uSec, "1"=50+70uSec { dht22_val[j/8]|=1; // Make lsb 1 (else it remains 0) } j++; } if (verbose) { printf("%3d|", pulse_array[i]); if (linex <= 0) { printf("\n"); linex=8; } linex--; } }// for if (verbose) { printf("\n"); printf("values: "); for (i=0; i<5; i++) { printf("%3d.",dht22_val[i]); } printf("\n"); } // verify checksum and print the verified data humidity = (float) (dht22_val[0]*256+dht22_val[1])/10; temperature = (float) (dht22_val[2]*256+dht22_val[3])/10; if((j>=40)&&(dht22_val[4]==((dht22_val[0]+dht22_val[1]+dht22_val[2]+dht22_val[3])& 0xFF))) { printf("UDP %2d, humidity: %3.1f; temperature: %3.1f; INT. ", r+1, humidity, temperature); if (dflg) { send_2_server(sockfd, humidity, temperature); } else { if (debug) { printf("Invalid Checksum Msg: %2d, humidity: %2.1f; temperature: %2.1f; INT. \n", r+1, humidity, temperature); } }//else result = 1; } else { if (verbose) { printf("Invalid Checksum Msg: %2d, humidity: %2.1f; temperature: %2.1f; INT. \n", r+1, humidity, temperature); } } //delay(1100); // Really necessary? }//while return(attempts); }
/* ********************************************************************************* * dht22_read_old * * Reading the sensor using the brute force method. Call the wait routine several times. * this method is more compute intensive than calling the interrupt routine. * ********************************************************************************* */ int dht22_read_old(int r) { uint8_t lststate=HIGH; uint8_t counter=0; uint8_t j,i,k; uint8_t linex; //struct timespec tim; int attempts = 0; int result = 0; while ((result == 0) && (attempts++ < 100)) { j = 0; //tim.tv_sec = 0; //tim.tv_nsec = 1000; delay(50); for(i=0;i<5;i++) dht22_val[i]=0; // Initialize result to 0 //pullUpDnControl (DHT22PIN, PUD_UP); // Start with a HIGH value delay(1); // Wait a ms piHiPri (10); // Set Higher Priority // Send the request pulse pinMode(DHT22PIN,OUTPUT); digitalWrite(DHT22PIN,LOW); delay(24); // Wait 18 milli seconds digitalWrite(DHT22PIN,HIGH); delayMicroseconds(25); // Pull up 40 uSec ==>> 38 works MUCH better // Switch to input mode // pullUpDnControl (DHT22PIN, PUD_UP); // Set pin mode to input pinMode(DHT22PIN,INPUT); // // READ LOOP // for( i=0; i<MAX_TIME; i++) { counter=0; while(digitalRead(DHT22PIN)==lststate){ counter++; delayMicroseconds(1); if(counter>=255) // break while loop when 255 uSecs no change on pin break; } //lststate=digitalRead(DHT22PIN); if(counter>=255) break; // break for loop else lststate = 1 - lststate; // top 3 transistions (pulses) are ignored as are the // odd numbers which all should be around 50 uSec each if((i>=4)&&(i%2==0)) { dht22_val[j/8]<<=1; if(counter>16) { dht22_val[j/8]|=1; } pulse_array[i]=counter; j++; } else { pulse_array[i]=counter; } } // // RESULTS SECTION // if (debug) { printf("\n"); linex = 3; for (k=0; k< i; k++) { printf("%3d ",pulse_array[k]); if (linex <= 0) { linex = 16; printf("\n"); } linex--; } printf("\n"); if (j<40) { printf("ERROR: Not 40 bits but %d: ",j); printf("hum:%d.%d | temp:%d.%d\n", dht22_val[0],dht22_val[1],dht22_val[2],dht22_val[3]); //return (EXIT_FAILURE); } } // verify cheksum and print the verified data humidity = (float)(dht22_val[0]*256+ dht22_val[1])/10; temperature = (float)(dht22_val[2]*256+ dht22_val[3])/10; if((j>=40)&&(dht22_val[4]==((dht22_val[0]+dht22_val[1]+dht22_val[2]+dht22_val[3])& 0xFF))) { if (dflg) { send_2_server(sockfd, humidity, temperature); if (verbose) printf("humidity: %2.1f; temperature: %2.1f; ORG. \n", humidity, temperature); } else { if (debug) { printf("Invalid Checksum Msg: %2d, humidity: %2.1f; temperature: %2.1f; ORG. \n", r+1, humidity, temperature); } }//else result = 1; } } return (attempts); }