summaryrefslogtreecommitdiffstats
path: root/cpukit/pppd/rtemspppd.c
blob: 5a821cdfafc718a3d559790f894986f28e994dc5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

#include <rtems.h>
#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;


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;

  /* 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 */
        pppdmain(0, NULL);
      }
    }
  }

  /* terminate myself */
  rtems_task_delete(RTEMS_SELF);
}

int rtems_pppd_initialize(void)
{
  int                 iReturn = (int)-1;
  rtems_status_code   status;
  rtems_name          taskName;

  taskName = rtems_build_name( 'p', 'p', 'p', 'd' );
  status   = rtems_task_create(taskName,
                               RTEMS_PPPD_TASK_PRIORITY,
                               RTEMS_PPPD_TASK_STACK_SIZE,
                               RTEMS_PPPD_TASK_INITIAL_MODES,
                               RTEMS_DEFAULT_ATTRIBUTES,
                               &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;
  default:
    iReturn = (int)-1;
    break;
  }

  return ( iReturn );
}

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 );
}