Tuesday, May 18, 2010

MULTI THREADED WEB SERVER IN C SOURCE CODE(LODE PAGES FROM GIVEN FOLDER LOCATION AND PUBLISH THEM)


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
#define MYPORT 8080    // the port users will be connecting to
#define BACKLOG 10     // how many pending connections queue will hold
#define MAXDATASIZE 1000
//*********************************************************************
void sigchld_handler(int s)
{
    while(wait(NULL) > 0);
}
//*********************************************************************
//---------------------------httpRequest Method------------------------
void* httpRequest(void* data)
{
    int me = *((int*)data);
        char buf[MAXDATASIZE],requestLine[100],tmp[20];
        int a=0,k=0,b=0,received=-1;
//Get the Header lines from the client
        if ((received = recv(me, buf, 100, 0)) < 0)
        {
                perror("Failed to receive initial bytes from client");
        }
        buf[received-1]='\0';
//Extract the request line.
        while(buf[a]!= '\n')
        requestLine[a]=buf[a++];
//Get the "GET" word.
        while(requestLine[b] != ' ')
        tmp[b]= requestLine[b++];
        if (strcmp(tmp,"GET")==0)
        {
      //Extract the file name.
               char *fileName,*fl1,*fl2;
               fl1=strpbrk(requestLine,"/");
               fl2=strtok(fl1," ");
               fileName=strpbrk(fl2,"/");
      //Document root
        char document_root[10]="./html";
      //Prepend the path of the Document root so that the
      //file request is within the Document root
    if(strcmp(fileName,"/")==0)
        strcpy(fileName,strcat(document_root,"/index.html"));
    else
        strcpy(fileName,strcat(document_root,fileName));
     //Open the requested file.
    FILE *fp;
    int file_exist=1;
    fp=fopen(fileName, "r");       
    if (fp==NULL)   
             file_exist=0;
//Extract the extension and assign content type of that file-----------------------------------------------------------------
    char *filetype;
    char *type;
        int s='.';
    filetype=strrchr(fileName,s);
            if((strcmp(filetype,".htm"))==0 || (strcmp(filetype,".html"))==0)
            type="text/html";
        else if((strcmp(filetype,".jpg"))==0)
            type="image/jpeg";
        else if(strcmp(filetype,".gif")==0)
            type="image/gif";
        else if(strcmp(filetype,".txt")==0)
            type="text/plain";
        else if((strcmp(filetype,".ram")==0) || (strcmp(filetype,".ra")==0))
            type="audio/x-pn-realaudio";
        else
            type="application/octet-stream";
            char statusLine[100]="HTTP/1.0";
        char contentTypeLine[100]="Content-type: ";
        char entityBody[100]="<html>";
        if(file_exist==1)
        {
        //send status line and the content type line
            strcpy(statusLine,strcat(statusLine,"200 OK"));
            strcpy(statusLine,strcat(statusLine,"\r\n"));
            strcpy(contentTypeLine,strcat(contentTypeLine,type));
            strcpy(contentTypeLine,strcat(contentTypeLine,"\r\n"));
        }
        else
        {
            strcpy(statusLine,strcat(statusLine,"404 Not Found"));
            strcpy(statusLine,strcat(statusLine,"\r\n"));
            //send a blank line to indicate the end of the header lines   
            strcpy(contentTypeLine,strcat(contentTypeLine,"NONE"));
            strcpy(contentTypeLine,strcat(contentTypeLine,"\r\n"));   
            //send the entity body
            strcpy(entityBody,strcat(entityBody,"<HEAD><TITLE>404 Not Found</TITLE></HEAD>"));
            strcpy(entityBody,strcat(entityBody,"<BODY>Not Found</BODY></html>"));
            strcpy(entityBody,strcat(entityBody,"\r\n"));   
        }
    //send the status line and content type line.
    if ((send(me, statusLine,strlen(statusLine), 0) == -1) ||
                (send(me, contentTypeLine, strlen(contentTypeLine),0) == -1) ||
            (send(me,"\r\n", strlen("\r\n"), 0) == -1))
                        perror("Failed to send bytes to client");
        //send the entity body
        if (file_exist)
        {
            wchar_t read_char[1];
            while((read_char[0]=fgetc(fp))!=EOF)
            {    
                if(send(me,read_char,sizeof(char),0) == -1)
                    perror("Failed to send bytes to client");       
            }
        }
        else
        {
            if (send(me, entityBody, 100, 0) == -1)
                        perror("Failed to send bytes to client");          
               }
        close(me);           // Close the connection.
       pthread_exit(NULL);  //Existing from the threads.
    }
    else
        printf("Warning message\n");
}
//****************************************************************************************************************
//Main Method------------------------------------------------------------------
int main (void)
{
    int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
    struct sockaddr_in my_addr;    // my address information
    struct sockaddr_in their_addr; // connector's address information
    int sin_size;
    struct sigaction sa;
    int yes=1;
    pthread_t p_thread[3000];
    int thr_id,i=0;  
//Create the parent socket.   
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }
//Handy debugging trick that lets    
    if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
        perror("setsockopt");
        exit(1);
    }
//Build the server's Inernet address.   
    // bzero((char *) &my_addr, sizeof(my_addr));
    my_addr.sin_family = AF_INET;         // host byte order
    my_addr.sin_port = htons(MYPORT);     // short, network byte order
    my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
    memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
//Binding
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1) {
        perror("bind");
        exit(1);
    }
//Make this socket ready to accept connection requests.    
    if (listen(sockfd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }
    sa.sa_handler = sigchld_handler; // read all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }
    while(1)
   {  // main accept() loop
        sin_size = sizeof(struct sockaddr_in);
        if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,&sin_size)) == -1) {
            perror("accept");
            continue;
        }
    //Creates threads.
    thr_id = pthread_create(&p_thread[i++],NULL,httpRequest,(void*)&new_fd);
   }
    return 0;
}

Interrupts' and their usage in pic microchip circuit design

 

1. What is an interrupt?
Basically CPU executes the instructions of the program one by one, doing what it is told in a precise and linear way. An interrupt disturbs this order. Coming maybe when least expected, its function is to alert the CPU that some significant external event has happened, to stop it from what it is doing and force it (at greatest speed possible) to respond to what has happened. Originally this was applied to allow emergency external events to get the attention of the CPU, emergencies like power failure, the system overheating or major failure of a subsystem. Then CPU takes necessary actions

2. What is an ISR? What command is used in PIC to return from an ISR?
ISR is interrupt service routine so that basically handle the necessary actions should be taken when some interrupt happens. We can use ISR by configuring following few steps
ü    Start the ISR at the interrupt vector, location 0004
ü    Enable the interrupt that is to be used, by setting the enable bit in the INTCON register
ü    Set the Global Enable bit, GIE
ü    Clear the interrupt flag within the ISR

End the ISR with a retfie instruction. RETFIE is exactly like a return, but it also sets the global interrupt enable (GIE). When a hardware interrupt occurs, it clears GIE and executes what amounts to a CALL instruction. Using RETFIE allows us to enable interrupts and return to the main program all in one step

3. What is Interrupt Latency?
The purpose of the interrupt is to attract the attention of the CPU quickly, but actually how quickly does this happen? The time between the interrupt occurring and the CPU responding to it is called the latency. Actually this is based on hardware configurations of the device

4. What are Interrupt flag bits and mask bits?

Flag bits-The occurrence of the interrupt, even if it is only momentary, is thus recorded. The output of the bistable, the latched version of the interrupt, is called the interrupt flag. This is then gated with an enable signal, Interrupt is enable. Basically we checked flag bits to detect weather interrupt is occurs or not

Mask bits- These bits are used to select which interrupts can be enable. Some interrupts can turn off and turn on. So do that we can use those bits. The action of disabling an interrupt is sometimes called masking. some microcontrollers have interrupts that cannot be masked. These are always external and are used to connect to external interrupt signals of the greatest importance

5. What is the bit that needs to be set in order to enable External interrupt on RBO (0th bit of PortB)?
    bsf intcon,inte
    And we must select global interrupt enable bit

6. What are timers? What is a pre-scalar?
We can use timers to maintain periodic events. Timers provide the timing for a range of activity such as motor controlling and various other applications
        The external input path includes the option of inverting the signal with the     Exclusive OR gate, the inversion being controlled by bit T0SE which is appear in     option register. The output of the first multiplexer branches before reaching a     second multiplexer. This selects     either a direct path or the path taken through a     programmable prescaler.we can set 1 trigger for 255 triggers by setting this
7. What is a watch dog timer?
Big problem of computer system is that the software fails in some way and that the system locks up or becomes unresponsive. In a desktop computer such lock-up can be annoying and one would normally have to reboot. In an embedded system it can be disastrous, as there may be no user to notice that there is something wrong and maybe no user interface anyway. If we enable this timer it’s perioditically counting up and it reaches top value of it then it reset the program (reset means go to the beginning of the program) if we neet to avoid reset we have to clear that by our program time to time.

Timer0 interrupt generation Assembly code for microchip pic16f877

list p=16f877
include <dev_fam.inc> ;this file is checked and corrected
include <math16.inc> ;
include <p16f877.inc>
;**********************************************************
;DEFINITIONS:CONSTANTS
FALSE equ 0
TRUE equ 1
PP0 equ b'00000000' ;PIC program page
PP1 equ b'00001000'
PP2 equ b'00010000'
PP3 equ b'00011000'
;------------------------------------------------------------
; RAM variables
    ORG 0X20
;-------------------------------------------------------------
PROGRAMPAGE set PP0
    org 0x00 ;RESET VECTOR
    goto start ;RUN main routine
    org 0x04 ;Interrupt VECTOR
;you can enter your interrupt check routines here
    goto ISR
;------------------------------------------------------------------
    org 0xA0
    start
    ;code for Initialization of Timer0 and other bits
       BANKSEL   INTCON ;BANK2
       MOVLW   0xA0
       MOVWF   INTCON ;Global interrupt and TMR0 interrupt enabled
    ;set timer 0
    banksel TMR0
    movlw b'00000000'   
    movwf TMR0
    ;get one timer 0 inturrupt after 256 triggers
    banksel OPTION_REG
    movlw b'10000110'   
    movwf OPTION_REG
    ;set port B as output
    banksel TRISB
    movlw b'11110000'
    movwf TRISB        
    banksel PORTB
    movlw b'00000000'
    movwf PORTB
    loop
    ;loops forever until inturrupts come
    goto loop
    ISR
    ;handling the interrupt
       comf  PORTB,1    ; Toggle Port B
      BANKSEL   INTCON ;BANK0
       BCF      INTCON,2 ;CLEAR INTERRUPT FLAG
    Retfie ;return and set global in turrupt enable
    end
--------------------------------------------------------------------------