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