1#include <stdio.h> 2#include <string.h> 3#include <unistd.h> 4#include <signal.h> 5#include <sys/types.h> 6#include <sys/time.h> 7#include <sys/wait.h> 8#include <sys/socket.h> 9#include <netinet/in.h> 10#include <arpa/inet.h> 11#include <errno.h> 12#include <fcntl.h> 13#include <unistd.h> 14#include <arpa/inet.h> 15#include <net/if.h> 16#include <sys/ioctl.h> 17 18#include <bcmnvram.h> 19#include "iboxcom.h" 20#include "lp.h" 21 22#include <semaphore_mfp.h> 23 24#define SRV_PORT 9999 25#define PRINT(fmt, args...) printf(stderr, fmt, ## args) 26#define TRUE 1 27 28//#define WLANCFG "/etc/thttpd/www/cgi-bin/wlan.cfg" 29#define WLANCFG "/etc/linuxigd/WLANConfig11b" 30#define PRODUCTCFG "/etc/linuxigd/general.log" 31#define LAN_DEV "br0" 32 33 34DWORD RECV(int sockfd , PBYTE pRcvbuf , DWORD dwlen , struct sockaddr *from, int *fromlen , DWORD timeout); 35int waitsock(int sockfd , int sec , int usec); 36int closesocket(int sockfd); 37void readPrnID(char *prninfo); 38void readParPrnID(char *prninfo); 39void readUsbPrnID(char *prninfo); 40int check_par_usb_prn(void); 41int set_pid(int pid); //deliver process id to driver 42void sig_usr1(int sig); //signal handler to handle signal send from driver 43void sig_usr2(int sig); 44 45int timeup=0; 46 47/* global variables for interface settings */ 48/* add by James Yeh 2002/12/23 */ 49#define MAX_INTERFACE 5 50int g_intfCount = 0; 51char* g_intf[MAX_INTERFACE]; 52 53#define MAX_GETID_RETRY 10 54int g_retry = 0; 55 56char ssid_g[32]; 57char netmask_g[32]; 58char productid_g[32]; 59char temp_productid[32]; 60char firmver_g[16]; 61unsigned char mac[6] = { 0x00, 0x0c, 0x6e, 0xbd, 0xf3, 0xc5}; 62 63 64void load_sysparam(void) 65{ 66 char macstr[32]; 67 char macdigit[3]; 68 69 strncpy(ssid_g, nvram_safe_get("wl_ssid"), sizeof(ssid_g)); 70 strncpy(netmask_g, nvram_safe_get("lan_netmask"), sizeof(netmask_g)); 71 //strncpy(productid_g, nvram_safe_get("productid"), sizeof(productid_g)); 72 strncpy(temp_productid, nvram_safe_get("productid"), sizeof(temp_productid)); 73 if(!strcmp(temp_productid, "WL500gpv2")) 74 strncpy(productid_g, "WL-500gP V2", sizeof(productid_g)); 75 else if(!strcmp(temp_productid, "WL520gu")) 76 strncpy(productid_g, "WL-520GU", sizeof(productid_g)); 77 else 78 strncpy(productid_g, temp_productid, sizeof(productid_g)); 79 strncpy(firmver_g, nvram_safe_get("firmver"), sizeof(firmver_g)); 80 81 strcpy(macstr, nvram_safe_get("et0macaddr")); 82 //printf("mac: %d\n", strlen(macstr)); 83 if (strlen(macstr)!=0) ether_atoe(macstr, mac); 84} 85 86int main(int argc , char* argv[]) 87{ 88 int sockfd , clisockfd; 89 unsigned int clilen; 90 int childpid; 91 struct sockaddr_in serv_addr,cli_addr; 92 int broadcast = 1; 93 int count = 0; 94 int ret, unit; 95 struct timeval tv; 96 97 if(argc < 2) 98 { 99 printf("not enough parameters for infosvr\n"); 100 printf("infosvr netif...\n"); 101 exit(0); 102 } 103 104 105 // Write PID file 106 if (!set_pid(getpid())) // Add by Joey 107 { 108 printf("can not set process id\n"); 109 exit(0); 110 } 111 112 113 // Load system related static parameter 114 load_sysparam(); 115 116#ifdef WCLIENT 117 // Signal for other tools 118 signal(SIGUSR1, sig_usr1); 119 signal(SIGUSR2, sig_usr2); 120 121 122 // Start state transaction 123 sta_info_init(); 124#endif 125 126#ifdef PRNINFO //JYWeng: 20030325 for WL500g/WL500b 127 // Signal for reading Printer Information 128 signal(SIGALRM, sig_usr1); // Add by Joey 129 signal(SIGUSR1 , sig_usr1); 130 alarm(2); // Get ID for the first time 2 seconds later 131#endif 132 133 g_intfCount = argc - 1; 134 135 while(count < g_intfCount) 136 { 137 g_intf[count] = argv[count+1]; 138 count ++; 139 } 140 141 142 if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0 ) 143 { 144 PRINT("can't open datagram socket\n"); 145 perror("socket:"); 146 exit(0); 147 } 148 149 if(setsockopt(sockfd , SOL_SOCKET , SO_BROADCAST ,(char *)&broadcast,sizeof(broadcast)) == -1) 150 { 151 perror("setsockopt:"); 152 } 153 154 bzero((char *)&cli_addr , sizeof(cli_addr)); 155 cli_addr.sin_family = AF_INET; 156 cli_addr.sin_addr.s_addr = inet_addr("255.255.255.255"); 157 cli_addr.sin_port = htons(SRV_PORT); 158 159 bzero((char *)&serv_addr , sizeof(serv_addr)); 160 serv_addr.sin_family = AF_INET; 161 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 162 serv_addr.sin_port = htons(SRV_PORT); 163 164 if(bind(sockfd,(struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0 ) 165 { 166 PRINT("can't bind\n"); 167 perror("ERR:"); 168 exit(0); 169 } 170 171 while(TRUE) 172 { 173 int len,res; 174 fd_set fdvar; 175 char databuf[1024]; 176 177 FD_ZERO(&fdvar); 178 FD_SET(sockfd, &fdvar); 179 180 181 tv.tv_sec = 2; 182 tv.tv_usec = 0; 183 res = select( sockfd + 1 , &fdvar , NULL , NULL , &tv); 184 185 if(res == 1) 186 { 187 //printf("got packet\n"); 188 processReq(sockfd); 189 } 190#ifdef WCLIENT 191 sta_status_check(); 192#endif 193 } 194} 195 196int processReq(int sockfd) 197{ 198 IBOX_COMM_PKT_HDR* phdr; 199 int iLen , iRes , iCount , iRcv; 200 int fromlen; 201 char *hdr; 202 char pdubuf[INFO_PDU_LENGTH]; 203 struct sockaddr_in from_addr; 204 205 memset(pdubuf,0,sizeof(pdubuf)); 206 207 //PRINT("Enter processReq\n"); 208 209 if( waitsock(sockfd , 1 , 0) == 0) 210 { 211 return -1; 212 } 213 214 fromlen = sizeof(from_addr); 215 216 //Receive the complete PDU 217 iRcv = RECV(sockfd , pdubuf , INFO_PDU_LENGTH , (struct sockaddr *)&from_addr , &fromlen , 1); 218 219 if(iRcv != INFO_PDU_LENGTH) 220 { 221 closesocket(sockfd); 222 return(-1); 223 } 224 225 hdr = pdubuf; 226 227 processPacket(sockfd, hdr); 228 closesocket(sockfd); 229} 230 231/************************************/ 232/*** Receive the socket ***/ 233/*** with a timeout value ***/ 234/************************************/ 235DWORD RECV(int sockfd , PBYTE pRcvbuf , DWORD dwlen , struct sockaddr *from, int *fromlen , DWORD timeout) 236{ 237 238 if( waitsock(sockfd , timeout , 0) == 0) 239 { 240 //timeout 241 PRINT("RECV timeout %d\n",timeout); 242 return -1; 243 } 244 245 return recvfrom(sockfd, pRcvbuf , dwlen , 0 , from , fromlen ); 246} 247 248 249int waitsock(int sockfd , int sec , int usec) 250{ 251 struct timeval tv; 252 fd_set fdvar; 253 int res; 254 255 FD_ZERO(&fdvar); 256 FD_SET(sockfd, &fdvar); 257 258 tv.tv_sec = sec; 259 tv.tv_usec = usec; 260 261 res = select( sockfd + 1 , &fdvar , NULL , NULL , &tv); 262 263 return res; 264} 265 266int closesocket(int sockfd) 267{ 268 /* Clear the UDP socket */ 269 char dummy[1024]; 270 int iLen , res; 271 272 //PRINT("closesocket ... \n"); 273 274 res = waitsock(sockfd , 1 , 0); 275 276 //PRINT("waitsock res %d\n",res); 277 278 if(res == 1) 279 { 280 iLen = recvfrom(sockfd, dummy , sizeof(dummy) , 0,NULL,0 ); 281 } 282 else 283 { 284 iLen = 0; 285 } 286 287 //PRINT("iLen %d\n",iLen); 288 289 if(iLen == sizeof(dummy)) 290 { 291 res = waitsock(sockfd , 1 , 0); 292 } 293 else 294 { 295 return 0; 296 } 297 298 299 300 while(res == 1) 301 { 302 iLen = recvfrom(sockfd, dummy , sizeof(dummy) , 0,NULL,0 ); 303 //PRINT("iLen = %d\n",res); 304 res = waitsock(sockfd , 0 , 100); 305 } 306 307 return 0; 308 309} 310 311 312void readPrnID(char *prninfo) 313{ 314 char *token; 315 316 if(check_par_usb_prn() == TRUE) //uese USB when return TRUE 317 { 318 readUsbPrnID(prninfo); 319 } 320 else 321 { 322 readParPrnID(prninfo); 323 } 324} 325 326void deCR(char *str) 327{ 328 int i, len; 329 330 len = strlen(str); 331 for (i=0; i<len; i++) 332 { 333 if (*(str+i) == '\r' || *(str+i) == '\n', *(str+i) == '"') 334 { 335 *(str+i) = 0; 336 break; 337 } 338 } 339} 340 341void readUsbPrnID(char *prninfo) 342{ 343 char mfr[32]; 344 char model[64]; 345 int fd; 346 struct parport_splink_device_info prn_info; 347 348 PRINT("readUsbPrnID\n"); 349 350// if( (fd=open("/dev/usb/lp0", O_RDWR)) < 0 ) //Someone is opening the usb lp0 351 semaphore_wait(); 352 if(nvram_match("MFP_busy", "2") || (fd=open("/dev/usb/lp0", O_RDWR)) < 0 ) //Someone is opening the usb lp0 353 { 354 semaphore_post(); 355 356 FILE *fp; 357 358 fp=fopen("/proc/usblp/usblpid","r"); 359 360 if( fp != NULL) 361 { 362 char *tokenEntry; 363 char *tokenField; 364 char *manufac; 365 char *mod; 366 char buf[1024]; 367 char *token; 368 369 memset(mfr , 0 , sizeof(mfr)); 370 memset(model , 0 , sizeof(model)); 371 372 while ( fgets(buf, sizeof(buf), fp) != NULL ) 373 { 374 if(buf[0] == '\n') 375 { 376 PRINT("skip empty line\n"); 377 continue; 378 } 379 380 if(strncmp(buf , "Manufacturer=" , strlen("Manufacturer=")) == 0) 381 { 382 token= buf + strlen("Manufacturer="); 383 PRINT("Manufacturer token %s",token); 384 385 memccpy(mfr , token , '\n' , 31); 386 deCR(mfr); 387 } 388 389 if(strncmp(buf , "Model=" , strlen("Model=")) == 0) 390 { 391 token= buf + strlen("Model="); 392 PRINT("Model token %s",token); 393 394 memccpy(model , token , '\n' , 63); 395 deCR(model); 396 } 397 398 } 399 400 fclose(fp); 401 402 sprintf( prninfo , "%s %s", mfr , model ); 403 404 PRINT("PRINTER MODEL %s\n",prninfo); 405 } 406 else 407 { 408 sprintf( prninfo , " " ); 409 PRINT("open failed\n"); 410 } 411 } 412 else 413 { 414 415 if( ioctl(fd, LPGETID, &prn_info) <0 ) 416 { 417 PRINT("ioctl error\n"); 418 perror("ioctl"); 419 } 420 else 421 { 422 int i = 0; 423 424 //PRINT("manufacturer: %s\n",prn_info.mfr); 425 //PRINT("model: %s\n",prn_info.model); 426 //PRINT("class: %s\n",prn_info.class_name); 427 //PRINT("description: %s\n",prn_info.description); 428 429 memccpy(mfr , prn_info.mfr , 1 , 32); 430 memccpy(model , prn_info.model , 1 , 32); 431 432 sprintf( prninfo , "%s %s", mfr , model ); 433 434 PRINT("prninfo %s",prninfo); 435 436 } 437 438 close(fd); 439 semaphore_post(); 440 } 441} 442 443 444void readParPrnID(char *prninfo) 445{ 446 char mfr[32]; 447 char model[64]; 448 int fd; 449 struct parport_splink_device_info prn_info; 450 451 452 PRINT("readParPrnID\n"); 453 454 if( (fd=open("/dev/lp0", O_RDWR)) < 0 ) //Someone is opening the lp0 455 { 456 FILE *fp; 457 458 fp=fopen("/proc/sys/dev/parport/parport0/devices/lp/deviceid","r"); 459 460 if( fp != NULL) 461 { 462 /// 463 char *tokenEntry; 464 char *tokenField; 465 char *manufac; 466 char *mod; 467 char buf[1024]; 468 char *token; 469 470 memset(mfr , 0 , sizeof(mfr)); 471 memset(model , 0 , sizeof(model)); 472 473 while ( fgets(buf, sizeof(buf), fp) != NULL ) 474 { 475 if(buf[0] == '\n') 476 { 477 PRINT("skip empty line\n"); 478 continue; 479 } 480 481 if(strncmp(buf , "Manufacturer: " , strlen("Manufacturer: ")) == 0) 482 { 483 token= buf + strlen("Manufacturer: "); 484 PRINT("Manufacturer token %s",token); 485 486 memccpy(mfr , token , '\n' , 31); 487 deCR(mfr); 488 } 489 490 if(strncmp(buf , "Model: " , strlen("Model: ")) == 0) 491 { 492 token= buf + strlen("Model: "); 493 PRINT("Model token %s",token); 494 495 memccpy(model , token , '\n' , 63); 496 deCR(model); 497 } 498 499 } 500 501 fclose(fp); 502 503 sprintf( prninfo , "%s %s", mfr , model ); 504 505 PRINT("prninfo %s\n",prninfo); 506 } 507 else 508 { 509 sprintf( prninfo , " " ); 510 PRINT("open failed\n"); 511 } 512 513 } 514 else 515 { 516 517 if( ioctl(fd, LPGETID, &prn_info) <0 ) 518 { 519 //PRINT("ioctl error\n"); 520 } 521 else 522 { 523 int i = 0; 524 525 //PRINT("manufacturer: %s\n",prn_info.mfr); 526 //PRINT("model: %s\n",prn_info.model); 527 //PRINT("class: %s\n",prn_info.class_name); 528 //PRINT("description: %s\n",prn_info.description); 529 530 memccpy(mfr , prn_info.mfr , 1 , 32); 531 memccpy(model , prn_info.model , 1 , 32); 532 533 sprintf( prninfo , "%s %s", mfr , model ); 534 535 } 536 537 close(fd); 538 } 539} 540 541#ifdef PRNINFO 542#define ONLINE_STRING "On-Line" 543#define OFFLINE_STRING "Off-Line" 544 545void readPrnStatus(void) 546{ 547 FILE *fp; 548 char buf[64]; 549 char *ukeyword="PRINTER_USER=\""; 550 char *skeyword="PRINTER_STATUS=\""; 551 char *token; 552 char user[32]; 553 char status[32]; 554 555 fp = fopen("/var/state/printstatus.txt", "r"); 556 557 memset(user, 0, sizeof(user)); 558 memset(status, 0, sizeof(status)); 559 560 if (fp!=NULL) 561 { 562 while ( fgets(buf, sizeof(buf), fp) != NULL ) 563 { 564 if(buf[0] == '\n') 565 { 566 PRINT("skip empty line\n"); 567 continue; 568 } 569 570 if(strncmp(buf , ukeyword , strlen(ukeyword)) == 0) 571 { 572 token= buf + strlen(ukeyword); 573 PRINT("User token %s",token); 574 575 deCR(token); 576 strcpy(user, token); 577 } 578 else if(strncmp(buf , skeyword, strlen(skeyword)) == 0) 579 { 580 token= buf + strlen(skeyword); 581 PRINT("Status token %s",token); 582 583 deCR(token); 584 strcpy(status, token); 585 } 586 } 587 fclose(fp); 588 } 589 else strcpy(status, ONLINE_STRING); 590 nvram_set("printer_status_t", status); 591 nvram_set("printer_user_t", user); 592 593 return; 594} 595 596/* update current status of printer */ 597void sig_usr1(int sig) 598{ 599 char prninfo[256], status[32]; 600 int isUsb; 601 602 //fp=fopen("/etc/linuxigd/printer.log","w"); 603 604 memset( prninfo , 0 , sizeof(prninfo) ); 605 606 607 if(check_par_usb_prn() == TRUE) //uese USB when return TRUE 608 { 609 //fputs( "INTERFACE=USB\n" , fp ); 610 nvram_set("printer_ifname", "usb"); 611 readUsbPrnID(prninfo); 612 isUsb = 1; 613 } 614 else 615 { 616 // Goto this step, then printer must be turn on 617 //fputs( "INTERFACE=PAR\n" , fp ); 618 nvram_set("printer_ifname", "par"); 619 readParPrnID(prninfo); 620 isUsb = 0; 621 } 622 623 if (strcmp(prninfo, " ")==0 || strlen(prninfo)==0) 624 { 625 //fprintf(fp, "MODEL=\"\"\n"); 626 nvram_set("printer_model_t", ""); 627 628 if (!isUsb) 629 { 630 /* Retry, only when paraport is plugged and no device id is returned */ 631 printf("Try again 2 seconds later\n"); 632 g_retry++; 633 634 if (g_retry<MAX_GETID_RETRY) alarm(6); 635 else g_retry = 0; 636 } 637 } 638 else 639 { 640 //fprintf(fp, "MODEL=\"%s\"\n", prninfo); 641 nvram_set("printer_model_t", prninfo); 642 } 643 644 /* update status of printer */ 645 if (nvram_invmatch("printer_model_t", "")) 646 { 647 readPrnStatus(); 648 } 649 else 650 { 651 nvram_set("printer_status_t", ""); 652 nvram_set("printer_user_t", ""); 653 } 654 PRINT("Enter sig_usr1\n"); 655} 656#endif 657 658#ifdef WCLIENT 659extern int wl_scan_disabled; 660void sig_usr1(int sig) 661{ 662 //if (wl_scan_disabled) wl_scan_disabled=0; 663 //else wl_scan_disabled=1; 664 //sta_status_report(0, 1); 665 check_tools(); 666} 667 668void sig_alrm(int sig) 669{ 670 timeup = 1; 671} 672 673// Write current status of wireless 674void sig_usr2(int sig) 675{ 676 sta_status_report(NULL, 1); 677} 678#endif 679/* to check use usb or parport printer */ 680/* return TRUE when using USB */ 681/* James Yeh 2002/12/25 02:13 */ 682 683int check_par_usb_prn() 684{ 685 char buf[1024]; 686 char *token; 687 FILE *fp; 688 689#ifdef NO_PARALLEL 690 return TRUE; 691#else 692 fp=fopen("/proc/sys/dev/parport/parport0/devices/lp/deviceid","r"); 693 694 if( fp != NULL) 695 { 696 while ( fgets(buf, sizeof(buf), fp) != NULL ) 697 { 698 699 PRINT("lp:%s\n", buf); 700 701 if(buf[0] == '\n') 702 { 703 continue; 704 } 705 706 if(strncmp(buf , "status: " , strlen("status: ")) == 0) 707 { 708 token= buf + strlen("status: "); 709 710 PRINT("token[0] %d\n",token[0]); 711 712 fclose(fp); 713 714 715 if(token[0] == '0') 716 { 717 return(TRUE); 718 } 719 else 720 { 721 return(0); 722 } 723 break; 724 } 725 726 } 727 728 fclose(fp); 729 } 730#endif 731 732} 733 734 735/* Deliver pid to driver */ 736/* Add by Joey */ 737int set_pid(int pid) 738{ 739 FILE *fp; 740 int fd, ret=0; 741 struct print_buffer pb; 742 743#ifndef NO_PARALLEL 744 fd = open("/dev/lp0", O_RDWR); 745 746 if (fd<0) return 0; 747 748 if ((pb.buf = malloc(12)) == NULL) return 0; 749 750 sprintf(pb.buf, "%d", pid); 751 752 if (ioctl(fd, LPSETID, &pb)<0) 753 { 754 free(pb.buf); 755 return 0; 756 } 757 free(pb.buf); 758 759 close(fd); 760#endif 761 762 fp = fopen("/var/run/infosvr.pid", "w"); 763 fprintf(fp, "%d", pid); 764 fclose(fp); 765 766 return 1; 767} 768 769void sendInfo(int sockfd, char *pdubuf) 770{ 771 struct sockaddr_in cli; 772 IBOX_COMM_PKT_HDR hdr; 773 int count=0, err; 774 775 cli.sin_family = AF_INET; 776 cli.sin_addr.s_addr = inet_addr("255.255.255.255");; 777 cli.sin_port = htons(SRV_PORT); 778 779 while(count < g_intfCount) 780 { 781 //PRINT("g_intf[%d] %s\n",count,g_intf[count]); 782 err = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, g_intf[count] , IFNAMSIZ); 783 if(err != 0) 784 { 785 printf("%s\n",g_intf[count]); 786 perror("setsockopt:"); 787 } 788 789 if(sendto(sockfd , pdubuf , INFO_PDU_LENGTH , 0 ,(struct sockaddr *) &cli, sizeof(cli)) == -1) 790 { 791 perror("sendto:"); 792 } 793 count ++; 794 } 795 796 err = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, "" , IFNAMSIZ); 797 798 if(err != 0) 799 { 800 perror("setsockopt reset:"); 801 } 802} 803