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

📄 sys-ecos.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
//==========================================================================
//
//      src/sys-ecos.c
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Portions created by Nick Garnett are
// Copyright (C) 2003, 2004 eCosCentric Ltd.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD, 
// FreeBSD or other sources, and are covered by the appropriate
// copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================

/*
 * sys-bsd.c - System-dependent procedures for setting up
 * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.)
 *
 * Copyright (c) 1989 Carnegie Mellon University.
 * Copyright (c) 1995 The Australian National University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by Carnegie Mellon University and The Australian National University.
 * The names of the Universities may not be used to endorse or promote
 * products derived from this software without specific prior written
 * permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef lint
//static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/sys-bsd.c,v 1.17 1999/08/28 01:19:08 peter Exp $";
#endif
/*	$NetBSD: sys-bsd.c,v 1.1.1.3 1997/09/26 18:53:04 christos Exp $	*/

/*
 * TODO:
 */

//==========================================================================

#include <pkgconf/system.h>
#include <pkgconf/net.h>
#include <pkgconf/ppp.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <signal.h>
#define _KERNEL 1
#include <sys/param.h>
#undef _KERNEL
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>
#ifdef NetBSD1_2
#include <util.h>
#endif
#ifdef PPP_FILTER
#include <net/bpf.h>
#endif

#include <cyg/ppp/syslog.h>

#include <net/if.h>
#include <cyg/ppp/net/ppp_defs.h>
#include <cyg/ppp/net/if_ppp.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/in.h>

#ifdef IPX_CHANGE
#include <netipx/ipx.h>
#endif

#if RTM_VERSION >= 3
#include <sys/param.h>
#if defined(NetBSD) && (NetBSD >= 199703)
#include <netinet/if_inarp.h>
#else	/* NetBSD 1.2D or later */
#include <netinet/if_ether.h>
#endif
#endif

#include "cyg/ppp/pppd.h"
#include "cyg/ppp/fsm.h"
#include "cyg/ppp/ipcp.h"

#include "cyg/ppp/ppp_io.h"

#include <cyg/ppp/ppp.h>

//==========================================================================

static int rtm_seq;

static cyg_io_handle_t ppp_handle; /* IO subsystem handle to PPP stream */
struct tty ppp_tty;             /* dummy TTY structure */

static cyg_handle_t ppp_rtc;
static cyg_resolution_t ppp_rtc_resolution;

static int loop_slave = -1;
static int loop_master;

static unsigned char inbuf[PPP_MTU + PPP_HDRLEN + 100]; /* buffer for chars read from input */

static int sockfd = -1;		/* socket for doing interface ioctls */

static int if_is_up;		/* the interface is currently up */
static u_int32_t ifaddrs[2];	/* local and remote addresses we set */
static u_int32_t default_route_gateway;	/* gateway addr for default route */
static u_int32_t proxy_arp_addr;	/* remote addr for proxy arp */

/* Prototypes for procedures local to this file. */
static int dodefaultroute __P((u_int32_t, int));
static int get_ether_addr __P((u_int32_t, struct sockaddr_dl *));

static void wait_input_alarm(cyg_handle_t alarm, cyg_addrword_t data);
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
void cyg_ppp_serial_callback( cyg_serial_line_status_t *s,
                                     CYG_ADDRWORD priv );
#endif

extern u_int32_t netmask;	/* IP netmask to set on interface */

//==========================================================================
/*
 * sys_init - System-dependent initialization.
 */
void
sys_init()
{
    if( sockfd == -1 )
    {
        /* Get an internet socket for doing socket ioctl's on. */
        if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
            syslog(LOG_ERR, "Couldn't create IP socket: %d",errno);
            die(1);
        }
    }

    ppp_tty.pppd_wakeup = 0;
    ppp_tty.pppd_thread_running = true;
    
    ppp_rtc = cyg_real_time_clock();
    ppp_rtc_resolution = cyg_clock_get_resolution( ppp_rtc );

    cyg_alarm_create( ppp_rtc,
                      wait_input_alarm,
                      (cyg_addrword_t)&ppp_tty,
                      &ppp_tty.alarm,
                      &ppp_tty.alarm_obj);
}

//==========================================================================
/*
 * sys_cleanup - restore any system state we modified before exiting:
 * mark the interface down, delete default route and/or proxy arp entry.
 * This should call die() because it's called from die().
 */
void
sys_cleanup()
{
    struct ifreq ifr;

db_printf("%s called\n", __PRETTY_FUNCTION__);
    if (if_is_up) {
	strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
	if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0
	    && ((ifr.ifr_flags & IFF_UP) != 0)) {
	    ifr.ifr_flags &= ~IFF_UP;
	    ioctl(sockfd, SIOCSIFFLAGS, &ifr);
	}
    }
    if (ifaddrs[0] != 0)
	cifaddr(0, ifaddrs[0], ifaddrs[1]);
    if (default_route_gateway)
	cifdefaultroute(0, 0, default_route_gateway);
    if (proxy_arp_addr)
	cifproxyarp(0, proxy_arp_addr);

    if( sockfd != -1 )
    {
        close(sockfd);
        sockfd = -1;
    }
}

//==========================================================================

#ifdef __ECOS

void
sys_exit(void)
{
db_printf("%s called\n", __PRETTY_FUNCTION__);    
    phase = PHASE_DEAD;
    while( ppp_tty.tx_thread_running )
    {
        db_printf("kick tx thread\n");        
        cyg_semaphore_post( &ppp_tty.tx_sem );
        cyg_thread_delay(100);
    }
    ppp_tty.pppd_thread_running = false;
    cyg_thread_exit();
}
#endif

//==========================================================================
/*
 * sys_close - Clean up in a child process before execing.
 */
void
sys_close()
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
    if (loop_slave >= 0) {
	close(loop_slave);
	close(loop_master);
    }
}

//==========================================================================
/*
 * sys_check_options - check the options that the user specified
 */
void
sys_check_options()
{
//db_printf("%s called\n", __PRETTY_FUNCTION__);
}

//==========================================================================
/*
 * ppp_available - check whether the system has any ppp interfaces
 * (in fact we check whether we can do an ioctl on ppp0).
 */
int
ppp_available()
{
    int s, ok;
    struct ifreq ifr;
    extern char *no_ppp_msg;

    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	return 1;		/* can't tell */

    strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
    ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
    close(s);

    no_ppp_msg = "\This system lacks kernel support for PPP.  To include PPP support\n\in the kernel, please follow the steps detailed in the README.bsd\n\file in the ppp-2.2 distribution.\n";
    return ok;
}

//==========================================================================
/*
 * establish_ppp - Turn the serial port into a ppp interface.
 */
void
establish_ppp(cyg_io_handle_t handle)
{
    int s;
    int x;
    int err;
    
//db_printf("%s called\n", __PRETTY_FUNCTION__);

    ppp_handle = ppp_tty.t_handle = handle;
    ppp_tty.t_sc = NULL;

    s = splsoftnet();

    err = cyg_ppp_pppopen( &ppp_tty );
    
    if( err != 0 )
        syslog( LOG_ERR, "Couldn't establish PPP interface: %d", err );

    /*
     * Enable debug in the driver if requested.
     */
    if (kdebugflag) {
	if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) < 0) {
	    syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %d",err);
	} else {
	    x |= (kdebugflag & 0xFF) * SC_DEBUG;
	    if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) < 0)
		syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %d",err);
	}
    }

    splx(s);
}

//==========================================================================
/*
 * restore_loop - reattach the ppp unit to the loopback.
 */
void
restore_loop()
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}


//==========================================================================
/*
 * disestablish_ppp - Restore the serial port to normal operation.
 * This shouldn't call die() because it's called from die().
 */
void
disestablish_ppp(cyg_io_handle_t handle)
{
    db_printf("%s called\n", __PRETTY_FUNCTION__);
}

//==========================================================================
/*
 * Check whether the link seems not to be 8-bit clean.
 */
void
clean_check()
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}

//==========================================================================
/*
 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
 * at the requested speed, etc.  If `local' is true, set CLOCAL
 * regardless of whether the modem option was specified.
 *
 * For *BSD, we assume that speed_t values numerically equal bits/second.
 */
void
set_up_tty(cyg_io_handle_t handle, int local)
{
    cyg_serial_info_t   cfg;
    int                 err;
    int                 len = sizeof(cfg);

    err = cyg_io_get_config( handle,
                             CYG_IO_GET_CONFIG_SERIAL_INFO,
                             &cfg,
                             &len);

    if( err != 0 ) {
	syslog(LOG_ERR, "cyg_io_get_config: %d",err);
	die(1);
    }

    switch ( flowctl )
    {
    case CYG_PPP_FLOWCTL_DEFAULT:
        break;
        
    case CYG_PPP_FLOWCTL_NONE:
        cfg.flags &= ~(CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX|
                       CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX);
        break;
        
    case CYG_PPP_FLOWCTL_HARDWARE:
        cfg.flags &= ~(CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX);
        cfg.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX;
        break;
        
    case CYG_PPP_FLOWCTL_SOFTWARE:
        cfg.flags &= ~(CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX);
        cfg.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX;
        break;
    }

    if( inspeed != 0 )
        cfg.baud = inspeed;
    
    err = cyg_io_set_config( handle,
                             CYG_IO_SET_CONFIG_SERIAL_INFO,
                             &cfg,
                             &len);

    if( err != 0 ) {
	syslog(LOG_ERR, "cyg_io_set_config: %d",err);
	die(1);
    }
}

//==========================================================================
/*
 * restore_tty - restore the terminal to the saved settings.
 */
void
restore_tty(cyg_io_handle_t handle)
{
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
    if( modem )
    {
        // Restore callback handler if it was set.
        
        Cyg_ErrNo err;
        cyg_uint32 len = sizeof(ppp_tty.serial_callbacks);

        db_printf("%s called\n", __PRETTY_FUNCTION__);
                
        err = cyg_io_set_config( handle,
                                 CYG_IO_SET_CONFIG_SERIAL_STATUS_CALLBACK,
                                 &ppp_tty.serial_callbacks,
                                 &len);

        if( err != 0 ) {
            syslog(LOG_ERR, "cyg_io_set_config(restore serial callbacks): %d",err);
            die(1);
        }
    }
#endif
}

//==========================================================================
/*
 * setdtr - control the DTR line on the serial port.
 * This is called from die(), so it shouldn't call die().
 */
void
setdtr(fd, on)
int fd, on;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}

//==========================================================================
/*

⌨️ 快捷键说明

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