#include #include #include "pppd.h" #include "rtemspppd.h" /* define pppd function prototypes */ extern void pppasyncattach(void); extern int pppdmain(int, char **); /* define global variables */ rtems_id rtems_pppd_taskid; rtems_pppd_hookfunction rtems_pppd_errorfp; rtems_pppd_hookfunction rtems_pppd_exitfp; static rtems_task pppTask(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_option options; rtems_event_set in; rtems_event_set out; int iStatus; /* call function to setup ppp line discipline */ pppasyncattach(); /* enter processing loop */ in = (RTEMS_EVENT_29 | RTEMS_EVENT_30); options = (RTEMS_EVENT_ANY | RTEMS_WAIT); while ( sc == RTEMS_SUCCESSFUL ) { /* wait for the next event */ sc = rtems_event_receive(in, options, RTEMS_NO_TIMEOUT, &out); if ( sc == RTEMS_SUCCESSFUL ) { /* determine which event was sent */ if ( out & RTEMS_EVENT_29 ) { /* terminate event received */ /* set value to break out of event loop */ sc = RTEMS_UNSATISFIED; } else if ( out & RTEMS_EVENT_30 ) { /* connect request */ /* execute the pppd main code */ iStatus = pppdmain(0, NULL); if ( iStatus == EXIT_OK ) { /* check exit callback */ if ( rtems_pppd_exitfp ) { (*rtems_pppd_exitfp)(); } } else { /* check error callback */ if ( rtems_pppd_errorfp ) { (*rtems_pppd_errorfp)(); } } } } } /* terminate myself */ rtems_pppd_taskid = 0; rtems_task_delete(RTEMS_SELF); } int rtems_pppd_initialize(void) { int iReturn = (int)-1; rtems_unsigned32 priority = 100; rtems_status_code status; rtems_name taskName; /* determine priority value */ if ( rtems_bsdnet_config.network_task_priority ) { priority = rtems_bsdnet_config.network_task_priority; } /* initialize the exit hook */ rtems_pppd_exitfp = (rtems_pppd_hookfunction)0; /* create the rtems task */ taskName = rtems_build_name( 'p', 'p', 'p', 'd' ); status = rtems_task_create(taskName, priority, 8192, (RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0)), RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL, &rtems_pppd_taskid); if ( status == RTEMS_SUCCESSFUL ) { status = rtems_task_start(rtems_pppd_taskid, pppTask, 0); if ( status == RTEMS_SUCCESSFUL ) { iReturn = rtems_pppd_reset_options(); } } return ( iReturn ); } int rtems_pppd_terminate(void) { /* send terminate signal to pppd task */ rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_29); /* call the disconnect function */ rtems_pppd_disconnect(); return ( 0 ); } int rtems_pppd_reset_options(void) { int i; struct protent *protp; /* * Initialize to the standard option set, then parse, in order, * the system options file, the user's options file, * the tty's options file, and the command line arguments. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(0); return ( 0 ); } int rtems_pppd_set_hook(int id, rtems_pppd_hookfunction hookfp) { int iReturn = (int)0; switch ( id ) { case RTEMS_PPPD_LINKUP_HOOK: auth_linkup_hook = hookfp; break; case RTEMS_PPPD_LINKDOWN_HOOK: auth_linkdown_hook = hookfp; break; case RTEMS_PPPD_IPUP_HOOK: ip_up_hook = hookfp; break; case RTEMS_PPPD_IPDOWN_HOOK: ip_down_hook = hookfp; break; case RTEMS_PPPD_ERROR_HOOK: rtems_pppd_errorfp = hookfp; break; case RTEMS_PPPD_EXIT_HOOK: rtems_pppd_exitfp = hookfp; break; default: iReturn = (int)-1; break; } return ( iReturn ); } int rtems_pppd_set_dialer(rtems_pppd_dialerfunction dialerfp) { pppd_dialer = dialerfp; return ( (int)0 ); } int rtems_pppd_set_option(const char *pOption, const char *pValue) { int iReturn = (int)0; int prevPhase; struct wordlist option; struct wordlist value; if ( pOption != (const char *)0 ) { /* initialize the values */ option.word = (char *)pOption; option.next = (struct wordlist *)0; if ( pValue != (const char *)0 ) { option.next = &value; value.word = (char *)pValue; value.next = (struct wordlist *)0; } /* save current phase value */ prevPhase = phase; phase = PHASE_INITIALIZE; /* process option and reset phase value */ iReturn = options_from_list(&option, 1); phase = prevPhase; } return ( iReturn ); } int rtems_pppd_connect(void) { /* send connect signal to pppd task */ rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_30); return ( 0 ); } int rtems_pppd_disconnect(void) { /* set pppd global variables to disconnect */ persist = 0; kill_link = 1; /* send event to wake up the pppd code */ /* pretend its a serial interrput */ rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_31); return ( 0 ); }