⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p16_http.c

📁 一个由PIC单片机组成的Web服务器源码
💻 C
字号:
/* HTTP support for ChipWeb  - Copyright (c) Iosoft Ltd 2001
**
** This source code is only licensed for distribution in the Iosoft ChipWeb
** package, and the purchaser of that package is granted the non-exclusive
** right to use the software for personal experimentation only, provided
** that this copyright notice is retained. All other rights are retained by
** Iosoft Ltd.
**
** Redistribution of this source code is not permitted. Binary images derived
** from the source code may only be redistributed if a commercial license is
** obtained; see www.iosoft.co.uk or email license@iosoft.co.uk
**
** The software is supplied 'as-is' for development purposes, without warranty
** of any kind, either expressed or implied, including, but not limited to,
** the implied warranties of merchantability and fitness for purpose.
** In no event will Iosoft Ltd. be liable for damages, including any general,
** special, incidental or consequential damages arising out of the use or
** inability to use the software, including, but not limited to, loss or
** corruption of data, or losses sustained by the developer or third parties,
** or failure of the software to operate with any other software or systems.
** This license shall be governed by the laws of England. */

#define HTTP_FAIL       "HTTP/ 200 OK\r\n\r\nNo Web pages!\r\n"

#define MAXFILES    100     // Limit on ROM file count (to stop runaway)
typedef union               // ROM file directory entry format
{
    ROM_FNAME f;                // Union of filename..
    BYTE b[sizeof(ROM_FNAME)];  // ..with byte values for i2c transfer
} ROM_DIR;

ROM_DIR romdir;             // Storage for one directory entry
BYTE fileidx;               // Index of current file (1=first, 0=error)

void check_formargs(void);
BOOL find_file(void);
void open_file(void);
void close_file(void);
BOOL tx_file_byte(void);
void putnic_volts(WORD val);

/* Receive an incoming HTTP request ('method'), return 0 if invalid */
SEPARATED BOOL http_recv(void)
{
    BYTE i, b, idx;
    char c;
    BYTE v;
    WORD val;
    checkflag = checkhi = checklo = 0;
    rx_checkoff = 1;
    DEBUG_PUTC('h');
    if (match_byte('G') && match_byte('E') && match_byte('T'))
    {
        match_byte(' ');
        match_byte('/');            // Start of filename
        DEBUG_PUTC(' ');
        for (i=0; i<ROM_FNAMELEN && get_byte(&c) && c>' ' && c!='?'; i++)
        {                           // Name terminated by space or '?'
            DEBUG_PUTC(c);
            romdir.f.name[i] = c;
        }
        for (; i<ROM_FNAMELEN; i++) // Blank rest of name
        {
            romdir.f.name[i] = 0;
        }                           // If file found in ROM
        if (find_file())
        {                           // ..check for form arguments
            DEBUG_PUTC('>');
            check_formargs();
        }
        else                        // File not found, get index.htm
        {
            DEBUG_PUTC('?');
            romdir.f.name[0] = 0;
            find_file();
        }
        checkhi = checklo = 0;
        checkflag = 0;
        txin = IPHDR_LEN + TCPHDR_LEN;
        if (!fileidx)               // No files at all in ROM - disaster!
        {
//            print_lcd = print_serial = FALSE;
//            print_net = TRUE;
//            setpos_txin(TCPIPHDR_LEN);
            putstr(HTTP_FAIL);
//            tflags = TFIN+TACK;     // Ack & close connection
//            tcp_xmit(tflags);
        }
        else                        // File found OK
        {
            open_file();                // Start i2c transfer
            while (romdir.f.len)
            {
                b = i2c_read(1);                // Get next byte from ROM
                romdir.f.len--;
                if ((romdir.f.flags&EGI_ATVARS) && b=='@' && romdir.f.len)
                {                               // If '@' and EGI var substitution..
                    b = i2c_read(1);            // ..get 2nd byte
                    romdir.f.len--;
                    idx = b - 0x30;
                    val = idx&1 ? adc1 : adc2;
                    if (idx==1 || idx==2)
                    {
                        v = (BYTE)((val * 25) >> 8) + 6 ;
                        if (v > 9)
                        {
                            if (v >= 99)
                                i = v = 9;
                            else for (i=0; i<10 && v>9; i++)
                                v -= 10;
                            put_byte(i + '0');
                        }
                        put_byte(v + '0');
                    }
                    else if (idx==3 || idx==4)  // Voltage value for ADC 1 or 2
                    {
                        v = (BYTE)((val * 25) >> 9);
                        for (i=0; i<10 && v>9; i++)
                            v -= 10;
                        put_byte(i + '0');
                        put_byte('.');
                        put_byte(v + '0');
                    }
                    else if (idx == 5)          // User O/P LED 1 state
                        put_byte(USERLED1 ? '0' : '1');
                    else if (idx == 6)          // User O/P LED 2 state
                        put_byte(USERLED2 ? '0' : '1');
                    else if (idx == 7)          // I/P button state
                        put_byte(USER_BUTTON ? '0' : '1');
                    else                        // Unknown variable
                        put_byte('?');
                }
                else                            // Non-EGI byte; send out unmodified
                    put_byte(b);
            }

            close_file();
//            tflags = TFIN+TPUSH+TACK;   // Close connection when sent
        }
        return(1);
    }
    return(0);
}

/* Check for arguments in HTTP request string
** Simple version: just check last 2 digits of filename, copy to 2 LEDs */
void check_formargs(void)
{
    if (romdir.f.name[6]=='0' || romdir.f.name[6]=='1')
        USERLED1 = (romdir.f.name[6] == '0');
    if (romdir.f.name[7]=='0' || romdir.f.name[7]=='1')
        USERLED2 = (romdir.f.name[7] == '0');
}

/* Find a filename in ROM filesystem. Return false if not found
** Sets fileidx to 0 if ROM error, 1 if file is first in ROM, 2 if 2nd..
** and leaves directory info in 'romdir'
** If the first byte of name is zero, match first directory entry */
BOOL find_file(void)
{
    BYTE mismatch=1, i, b;
    char temps[ROM_FNAMELEN];

    fileidx = 0;                        // Set ROM address pointer to 0
    i2c_start();
    i2c_write(EEROM_ADDR);
    i2c_write(0);
    i2c_write(0);
    i2c_stop();
    do
    {
        i2c_start();                    // Read next directory entry
        i2c_write(EEROM_ADDR | 1);
#if 1
        for (i=0; i<7; i++)
            romdir.b[i] = i2c_read(1);
        if (romdir.b[0]==0xff && romdir.b[1]==0xff)
        {                               // Abandon if no entry
            i2c_read(0);
            break;
        }
        else
        {
#else
        if ((romdir.b[0] = i2c_read(1)) == 0xff)
        {                               // Abandon if no entry
//            end = 1;
            i2c_read(0);
            break;
        }
        else
        {                               // Get file len, ptr, csum and flags
            for (i=1; i<7; i++)
                romdir.b[i] = i2c_read(1);
#endif
            mismatch = 0;               // Try matching name
            for (i=0; i<ROM_FNAMELEN; i++)
            {
                temps[i] = b = i2c_read(i<ROM_FNAMELEN-1);
                if (b != romdir.f.name[i])
                    mismatch = 1;
            }
            if (!romdir.f.name[0])      // If null name, match anything
                mismatch = 0;
        }
        i2c_stop();                     // Loop until matched
        fileidx++;
    } while (fileidx<MAXFILES && mismatch);
    if (mismatch)
        romdir.f.len = 0;
    return(!mismatch);
}

/* Open the previously-found file for transmission */
void open_file(void)
{
    i2c_start();
    i2c_write(EEROM_ADDR);              // Write start pointer to eerom
    i2c_write(romdir.f.start >> 8);
    i2c_write(romdir.f.start);
    i2c_stop();
    i2c_start();
    i2c_write(EEROM_ADDR | 1);          // Restart ROM access as read cycle
}

/* Close the previously-opened file */
void close_file(void)
{
    i2c_read(0);                        // Dummy read cycle without ACK
    i2c_stop();
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -