Leest de waarde van een sensor binnen een maakt deze beschikbaar via internet

Dependencies:   NTPClient_NetServices mbed

Committer:
hendrikvincent
Date:
Mon Dec 02 09:01:23 2013 +0000
Revision:
0:05ccbd4f84f1
eerste programma;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hendrikvincent 0:05ccbd4f84f1 1 /*****************************************************************************
hendrikvincent 0:05ccbd4f84f1 2 * fsm.c - Network Control Protocol Finite State Machine program file.
hendrikvincent 0:05ccbd4f84f1 3 *
hendrikvincent 0:05ccbd4f84f1 4 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
hendrikvincent 0:05ccbd4f84f1 5 * portions Copyright (c) 1997 by Global Election Systems Inc.
hendrikvincent 0:05ccbd4f84f1 6 *
hendrikvincent 0:05ccbd4f84f1 7 * The authors hereby grant permission to use, copy, modify, distribute,
hendrikvincent 0:05ccbd4f84f1 8 * and license this software and its documentation for any purpose, provided
hendrikvincent 0:05ccbd4f84f1 9 * that existing copyright notices are retained in all copies and that this
hendrikvincent 0:05ccbd4f84f1 10 * notice and the following disclaimer are included verbatim in any
hendrikvincent 0:05ccbd4f84f1 11 * distributions. No written agreement, license, or royalty fee is required
hendrikvincent 0:05ccbd4f84f1 12 * for any of the authorized uses.
hendrikvincent 0:05ccbd4f84f1 13 *
hendrikvincent 0:05ccbd4f84f1 14 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
hendrikvincent 0:05ccbd4f84f1 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
hendrikvincent 0:05ccbd4f84f1 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
hendrikvincent 0:05ccbd4f84f1 17 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
hendrikvincent 0:05ccbd4f84f1 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
hendrikvincent 0:05ccbd4f84f1 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
hendrikvincent 0:05ccbd4f84f1 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
hendrikvincent 0:05ccbd4f84f1 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
hendrikvincent 0:05ccbd4f84f1 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
hendrikvincent 0:05ccbd4f84f1 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
hendrikvincent 0:05ccbd4f84f1 24 *
hendrikvincent 0:05ccbd4f84f1 25 ******************************************************************************
hendrikvincent 0:05ccbd4f84f1 26 * REVISION HISTORY
hendrikvincent 0:05ccbd4f84f1 27 *
hendrikvincent 0:05ccbd4f84f1 28 * 03-01-01 Marc Boucher <marc@mbsi.ca>
hendrikvincent 0:05ccbd4f84f1 29 * Ported to lwIP.
hendrikvincent 0:05ccbd4f84f1 30 * 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
hendrikvincent 0:05ccbd4f84f1 31 * Original based on BSD fsm.c.
hendrikvincent 0:05ccbd4f84f1 32 *****************************************************************************/
hendrikvincent 0:05ccbd4f84f1 33 /*
hendrikvincent 0:05ccbd4f84f1 34 * fsm.c - {Link, IP} Control Protocol Finite State Machine.
hendrikvincent 0:05ccbd4f84f1 35 *
hendrikvincent 0:05ccbd4f84f1 36 * Copyright (c) 1989 Carnegie Mellon University.
hendrikvincent 0:05ccbd4f84f1 37 * All rights reserved.
hendrikvincent 0:05ccbd4f84f1 38 *
hendrikvincent 0:05ccbd4f84f1 39 * Redistribution and use in source and binary forms are permitted
hendrikvincent 0:05ccbd4f84f1 40 * provided that the above copyright notice and this paragraph are
hendrikvincent 0:05ccbd4f84f1 41 * duplicated in all such forms and that any documentation,
hendrikvincent 0:05ccbd4f84f1 42 * advertising materials, and other materials related to such
hendrikvincent 0:05ccbd4f84f1 43 * distribution and use acknowledge that the software was developed
hendrikvincent 0:05ccbd4f84f1 44 * by Carnegie Mellon University. The name of the
hendrikvincent 0:05ccbd4f84f1 45 * University may not be used to endorse or promote products derived
hendrikvincent 0:05ccbd4f84f1 46 * from this software without specific prior written permission.
hendrikvincent 0:05ccbd4f84f1 47 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
hendrikvincent 0:05ccbd4f84f1 48 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
hendrikvincent 0:05ccbd4f84f1 49 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
hendrikvincent 0:05ccbd4f84f1 50 */
hendrikvincent 0:05ccbd4f84f1 51
hendrikvincent 0:05ccbd4f84f1 52 /*
hendrikvincent 0:05ccbd4f84f1 53 * TODO:
hendrikvincent 0:05ccbd4f84f1 54 * Randomize fsm id on link/init.
hendrikvincent 0:05ccbd4f84f1 55 * Deal with variable outgoing MTU.
hendrikvincent 0:05ccbd4f84f1 56 */
hendrikvincent 0:05ccbd4f84f1 57
hendrikvincent 0:05ccbd4f84f1 58 #include "lwip/opt.h"
hendrikvincent 0:05ccbd4f84f1 59
hendrikvincent 0:05ccbd4f84f1 60 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
hendrikvincent 0:05ccbd4f84f1 61
hendrikvincent 0:05ccbd4f84f1 62 #include "ppp.h"
hendrikvincent 0:05ccbd4f84f1 63 #include "pppdebug.h"
hendrikvincent 0:05ccbd4f84f1 64
hendrikvincent 0:05ccbd4f84f1 65 #include "fsm.h"
hendrikvincent 0:05ccbd4f84f1 66
hendrikvincent 0:05ccbd4f84f1 67 #include <string.h>
hendrikvincent 0:05ccbd4f84f1 68
hendrikvincent 0:05ccbd4f84f1 69 #if PPP_DEBUG
hendrikvincent 0:05ccbd4f84f1 70 static const char *ppperr_strerr[] = {
hendrikvincent 0:05ccbd4f84f1 71 "LS_INITIAL", /* LS_INITIAL 0 */
hendrikvincent 0:05ccbd4f84f1 72 "LS_STARTING", /* LS_STARTING 1 */
hendrikvincent 0:05ccbd4f84f1 73 "LS_CLOSED", /* LS_CLOSED 2 */
hendrikvincent 0:05ccbd4f84f1 74 "LS_STOPPED", /* LS_STOPPED 3 */
hendrikvincent 0:05ccbd4f84f1 75 "LS_CLOSING", /* LS_CLOSING 4 */
hendrikvincent 0:05ccbd4f84f1 76 "LS_STOPPING", /* LS_STOPPING 5 */
hendrikvincent 0:05ccbd4f84f1 77 "LS_REQSENT", /* LS_REQSENT 6 */
hendrikvincent 0:05ccbd4f84f1 78 "LS_ACKRCVD", /* LS_ACKRCVD 7 */
hendrikvincent 0:05ccbd4f84f1 79 "LS_ACKSENT", /* LS_ACKSENT 8 */
hendrikvincent 0:05ccbd4f84f1 80 "LS_OPENED" /* LS_OPENED 9 */
hendrikvincent 0:05ccbd4f84f1 81 };
hendrikvincent 0:05ccbd4f84f1 82 #endif /* PPP_DEBUG */
hendrikvincent 0:05ccbd4f84f1 83
hendrikvincent 0:05ccbd4f84f1 84 static void fsm_timeout (void *);
hendrikvincent 0:05ccbd4f84f1 85 static void fsm_rconfreq (fsm *, u_char, u_char *, int);
hendrikvincent 0:05ccbd4f84f1 86 static void fsm_rconfack (fsm *, int, u_char *, int);
hendrikvincent 0:05ccbd4f84f1 87 static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);
hendrikvincent 0:05ccbd4f84f1 88 static void fsm_rtermreq (fsm *, int, u_char *, int);
hendrikvincent 0:05ccbd4f84f1 89 static void fsm_rtermack (fsm *);
hendrikvincent 0:05ccbd4f84f1 90 static void fsm_rcoderej (fsm *, u_char *, int);
hendrikvincent 0:05ccbd4f84f1 91 static void fsm_sconfreq (fsm *, int);
hendrikvincent 0:05ccbd4f84f1 92
hendrikvincent 0:05ccbd4f84f1 93 #define PROTO_NAME(f) ((f)->callbacks->proto_name)
hendrikvincent 0:05ccbd4f84f1 94
hendrikvincent 0:05ccbd4f84f1 95 int peer_mru[NUM_PPP];
hendrikvincent 0:05ccbd4f84f1 96
hendrikvincent 0:05ccbd4f84f1 97
hendrikvincent 0:05ccbd4f84f1 98 /*
hendrikvincent 0:05ccbd4f84f1 99 * fsm_init - Initialize fsm.
hendrikvincent 0:05ccbd4f84f1 100 *
hendrikvincent 0:05ccbd4f84f1 101 * Initialize fsm state.
hendrikvincent 0:05ccbd4f84f1 102 */
hendrikvincent 0:05ccbd4f84f1 103 void
hendrikvincent 0:05ccbd4f84f1 104 fsm_init(fsm *f)
hendrikvincent 0:05ccbd4f84f1 105 {
hendrikvincent 0:05ccbd4f84f1 106 f->state = LS_INITIAL;
hendrikvincent 0:05ccbd4f84f1 107 f->flags = 0;
hendrikvincent 0:05ccbd4f84f1 108 f->id = 0; /* XXX Start with random id? */
hendrikvincent 0:05ccbd4f84f1 109 f->timeouttime = FSM_DEFTIMEOUT;
hendrikvincent 0:05ccbd4f84f1 110 f->maxconfreqtransmits = FSM_DEFMAXCONFREQS;
hendrikvincent 0:05ccbd4f84f1 111 f->maxtermtransmits = FSM_DEFMAXTERMREQS;
hendrikvincent 0:05ccbd4f84f1 112 f->maxnakloops = FSM_DEFMAXNAKLOOPS;
hendrikvincent 0:05ccbd4f84f1 113 f->term_reason_len = 0;
hendrikvincent 0:05ccbd4f84f1 114 }
hendrikvincent 0:05ccbd4f84f1 115
hendrikvincent 0:05ccbd4f84f1 116
hendrikvincent 0:05ccbd4f84f1 117 /*
hendrikvincent 0:05ccbd4f84f1 118 * fsm_lowerup - The lower layer is up.
hendrikvincent 0:05ccbd4f84f1 119 */
hendrikvincent 0:05ccbd4f84f1 120 void
hendrikvincent 0:05ccbd4f84f1 121 fsm_lowerup(fsm *f)
hendrikvincent 0:05ccbd4f84f1 122 {
hendrikvincent 0:05ccbd4f84f1 123 int oldState = f->state;
hendrikvincent 0:05ccbd4f84f1 124
hendrikvincent 0:05ccbd4f84f1 125 LWIP_UNUSED_ARG(oldState);
hendrikvincent 0:05ccbd4f84f1 126
hendrikvincent 0:05ccbd4f84f1 127 switch( f->state ) {
hendrikvincent 0:05ccbd4f84f1 128 case LS_INITIAL:
hendrikvincent 0:05ccbd4f84f1 129 f->state = LS_CLOSED;
hendrikvincent 0:05ccbd4f84f1 130 break;
hendrikvincent 0:05ccbd4f84f1 131
hendrikvincent 0:05ccbd4f84f1 132 case LS_STARTING:
hendrikvincent 0:05ccbd4f84f1 133 if( f->flags & OPT_SILENT ) {
hendrikvincent 0:05ccbd4f84f1 134 f->state = LS_STOPPED;
hendrikvincent 0:05ccbd4f84f1 135 } else {
hendrikvincent 0:05ccbd4f84f1 136 /* Send an initial configure-request */
hendrikvincent 0:05ccbd4f84f1 137 fsm_sconfreq(f, 0);
hendrikvincent 0:05ccbd4f84f1 138 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 139 }
hendrikvincent 0:05ccbd4f84f1 140 break;
hendrikvincent 0:05ccbd4f84f1 141
hendrikvincent 0:05ccbd4f84f1 142 default:
hendrikvincent 0:05ccbd4f84f1 143 FSMDEBUG(LOG_INFO, ("%s: Up event in state %d (%s)!\n",
hendrikvincent 0:05ccbd4f84f1 144 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 145 }
hendrikvincent 0:05ccbd4f84f1 146
hendrikvincent 0:05ccbd4f84f1 147 FSMDEBUG(LOG_INFO, ("%s: lowerup state %d (%s) -> %d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 148 PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 149 }
hendrikvincent 0:05ccbd4f84f1 150
hendrikvincent 0:05ccbd4f84f1 151
hendrikvincent 0:05ccbd4f84f1 152 /*
hendrikvincent 0:05ccbd4f84f1 153 * fsm_lowerdown - The lower layer is down.
hendrikvincent 0:05ccbd4f84f1 154 *
hendrikvincent 0:05ccbd4f84f1 155 * Cancel all timeouts and inform upper layers.
hendrikvincent 0:05ccbd4f84f1 156 */
hendrikvincent 0:05ccbd4f84f1 157 void
hendrikvincent 0:05ccbd4f84f1 158 fsm_lowerdown(fsm *f)
hendrikvincent 0:05ccbd4f84f1 159 {
hendrikvincent 0:05ccbd4f84f1 160 int oldState = f->state;
hendrikvincent 0:05ccbd4f84f1 161
hendrikvincent 0:05ccbd4f84f1 162 LWIP_UNUSED_ARG(oldState);
hendrikvincent 0:05ccbd4f84f1 163
hendrikvincent 0:05ccbd4f84f1 164 switch( f->state ) {
hendrikvincent 0:05ccbd4f84f1 165 case LS_CLOSED:
hendrikvincent 0:05ccbd4f84f1 166 f->state = LS_INITIAL;
hendrikvincent 0:05ccbd4f84f1 167 break;
hendrikvincent 0:05ccbd4f84f1 168
hendrikvincent 0:05ccbd4f84f1 169 case LS_STOPPED:
hendrikvincent 0:05ccbd4f84f1 170 f->state = LS_STARTING;
hendrikvincent 0:05ccbd4f84f1 171 if( f->callbacks->starting ) {
hendrikvincent 0:05ccbd4f84f1 172 (*f->callbacks->starting)(f);
hendrikvincent 0:05ccbd4f84f1 173 }
hendrikvincent 0:05ccbd4f84f1 174 break;
hendrikvincent 0:05ccbd4f84f1 175
hendrikvincent 0:05ccbd4f84f1 176 case LS_CLOSING:
hendrikvincent 0:05ccbd4f84f1 177 f->state = LS_INITIAL;
hendrikvincent 0:05ccbd4f84f1 178 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 179 break;
hendrikvincent 0:05ccbd4f84f1 180
hendrikvincent 0:05ccbd4f84f1 181 case LS_STOPPING:
hendrikvincent 0:05ccbd4f84f1 182 case LS_REQSENT:
hendrikvincent 0:05ccbd4f84f1 183 case LS_ACKRCVD:
hendrikvincent 0:05ccbd4f84f1 184 case LS_ACKSENT:
hendrikvincent 0:05ccbd4f84f1 185 f->state = LS_STARTING;
hendrikvincent 0:05ccbd4f84f1 186 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 187 break;
hendrikvincent 0:05ccbd4f84f1 188
hendrikvincent 0:05ccbd4f84f1 189 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 190 if( f->callbacks->down ) {
hendrikvincent 0:05ccbd4f84f1 191 (*f->callbacks->down)(f);
hendrikvincent 0:05ccbd4f84f1 192 }
hendrikvincent 0:05ccbd4f84f1 193 f->state = LS_STARTING;
hendrikvincent 0:05ccbd4f84f1 194 break;
hendrikvincent 0:05ccbd4f84f1 195
hendrikvincent 0:05ccbd4f84f1 196 default:
hendrikvincent 0:05ccbd4f84f1 197 FSMDEBUG(LOG_INFO, ("%s: Down event in state %d (%s)!\n",
hendrikvincent 0:05ccbd4f84f1 198 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 199 }
hendrikvincent 0:05ccbd4f84f1 200
hendrikvincent 0:05ccbd4f84f1 201 FSMDEBUG(LOG_INFO, ("%s: lowerdown state %d (%s) -> %d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 202 PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 203 }
hendrikvincent 0:05ccbd4f84f1 204
hendrikvincent 0:05ccbd4f84f1 205
hendrikvincent 0:05ccbd4f84f1 206 /*
hendrikvincent 0:05ccbd4f84f1 207 * fsm_open - Link is allowed to come up.
hendrikvincent 0:05ccbd4f84f1 208 */
hendrikvincent 0:05ccbd4f84f1 209 void
hendrikvincent 0:05ccbd4f84f1 210 fsm_open(fsm *f)
hendrikvincent 0:05ccbd4f84f1 211 {
hendrikvincent 0:05ccbd4f84f1 212 int oldState = f->state;
hendrikvincent 0:05ccbd4f84f1 213
hendrikvincent 0:05ccbd4f84f1 214 LWIP_UNUSED_ARG(oldState);
hendrikvincent 0:05ccbd4f84f1 215
hendrikvincent 0:05ccbd4f84f1 216 switch( f->state ) {
hendrikvincent 0:05ccbd4f84f1 217 case LS_INITIAL:
hendrikvincent 0:05ccbd4f84f1 218 f->state = LS_STARTING;
hendrikvincent 0:05ccbd4f84f1 219 if( f->callbacks->starting ) {
hendrikvincent 0:05ccbd4f84f1 220 (*f->callbacks->starting)(f);
hendrikvincent 0:05ccbd4f84f1 221 }
hendrikvincent 0:05ccbd4f84f1 222 break;
hendrikvincent 0:05ccbd4f84f1 223
hendrikvincent 0:05ccbd4f84f1 224 case LS_CLOSED:
hendrikvincent 0:05ccbd4f84f1 225 if( f->flags & OPT_SILENT ) {
hendrikvincent 0:05ccbd4f84f1 226 f->state = LS_STOPPED;
hendrikvincent 0:05ccbd4f84f1 227 } else {
hendrikvincent 0:05ccbd4f84f1 228 /* Send an initial configure-request */
hendrikvincent 0:05ccbd4f84f1 229 fsm_sconfreq(f, 0);
hendrikvincent 0:05ccbd4f84f1 230 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 231 }
hendrikvincent 0:05ccbd4f84f1 232 break;
hendrikvincent 0:05ccbd4f84f1 233
hendrikvincent 0:05ccbd4f84f1 234 case LS_CLOSING:
hendrikvincent 0:05ccbd4f84f1 235 f->state = LS_STOPPING;
hendrikvincent 0:05ccbd4f84f1 236 /* fall through */
hendrikvincent 0:05ccbd4f84f1 237 case LS_STOPPED:
hendrikvincent 0:05ccbd4f84f1 238 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 239 if( f->flags & OPT_RESTART ) {
hendrikvincent 0:05ccbd4f84f1 240 fsm_lowerdown(f);
hendrikvincent 0:05ccbd4f84f1 241 fsm_lowerup(f);
hendrikvincent 0:05ccbd4f84f1 242 }
hendrikvincent 0:05ccbd4f84f1 243 break;
hendrikvincent 0:05ccbd4f84f1 244 }
hendrikvincent 0:05ccbd4f84f1 245
hendrikvincent 0:05ccbd4f84f1 246 FSMDEBUG(LOG_INFO, ("%s: open state %d (%s) -> %d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 247 PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 248 }
hendrikvincent 0:05ccbd4f84f1 249
hendrikvincent 0:05ccbd4f84f1 250 #if 0 /* backport pppd 2.4.4b1; */
hendrikvincent 0:05ccbd4f84f1 251 /*
hendrikvincent 0:05ccbd4f84f1 252 * terminate_layer - Start process of shutting down the FSM
hendrikvincent 0:05ccbd4f84f1 253 *
hendrikvincent 0:05ccbd4f84f1 254 * Cancel any timeout running, notify upper layers we're done, and
hendrikvincent 0:05ccbd4f84f1 255 * send a terminate-request message as configured.
hendrikvincent 0:05ccbd4f84f1 256 */
hendrikvincent 0:05ccbd4f84f1 257 static void
hendrikvincent 0:05ccbd4f84f1 258 terminate_layer(fsm *f, int nextstate)
hendrikvincent 0:05ccbd4f84f1 259 {
hendrikvincent 0:05ccbd4f84f1 260 /* @todo */
hendrikvincent 0:05ccbd4f84f1 261 }
hendrikvincent 0:05ccbd4f84f1 262 #endif
hendrikvincent 0:05ccbd4f84f1 263
hendrikvincent 0:05ccbd4f84f1 264 /*
hendrikvincent 0:05ccbd4f84f1 265 * fsm_close - Start closing connection.
hendrikvincent 0:05ccbd4f84f1 266 *
hendrikvincent 0:05ccbd4f84f1 267 * Cancel timeouts and either initiate close or possibly go directly to
hendrikvincent 0:05ccbd4f84f1 268 * the LS_CLOSED state.
hendrikvincent 0:05ccbd4f84f1 269 */
hendrikvincent 0:05ccbd4f84f1 270 void
hendrikvincent 0:05ccbd4f84f1 271 fsm_close(fsm *f, char *reason)
hendrikvincent 0:05ccbd4f84f1 272 {
hendrikvincent 0:05ccbd4f84f1 273 int oldState = f->state;
hendrikvincent 0:05ccbd4f84f1 274
hendrikvincent 0:05ccbd4f84f1 275 LWIP_UNUSED_ARG(oldState);
hendrikvincent 0:05ccbd4f84f1 276
hendrikvincent 0:05ccbd4f84f1 277 f->term_reason = reason;
hendrikvincent 0:05ccbd4f84f1 278 f->term_reason_len = (reason == NULL ? 0 : (int)strlen(reason));
hendrikvincent 0:05ccbd4f84f1 279 switch( f->state ) {
hendrikvincent 0:05ccbd4f84f1 280 case LS_STARTING:
hendrikvincent 0:05ccbd4f84f1 281 f->state = LS_INITIAL;
hendrikvincent 0:05ccbd4f84f1 282 break;
hendrikvincent 0:05ccbd4f84f1 283 case LS_STOPPED:
hendrikvincent 0:05ccbd4f84f1 284 f->state = LS_CLOSED;
hendrikvincent 0:05ccbd4f84f1 285 break;
hendrikvincent 0:05ccbd4f84f1 286 case LS_STOPPING:
hendrikvincent 0:05ccbd4f84f1 287 f->state = LS_CLOSING;
hendrikvincent 0:05ccbd4f84f1 288 break;
hendrikvincent 0:05ccbd4f84f1 289
hendrikvincent 0:05ccbd4f84f1 290 case LS_REQSENT:
hendrikvincent 0:05ccbd4f84f1 291 case LS_ACKRCVD:
hendrikvincent 0:05ccbd4f84f1 292 case LS_ACKSENT:
hendrikvincent 0:05ccbd4f84f1 293 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 294 if( f->state != LS_OPENED ) {
hendrikvincent 0:05ccbd4f84f1 295 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 296 } else if( f->callbacks->down ) {
hendrikvincent 0:05ccbd4f84f1 297 (*f->callbacks->down)(f); /* Inform upper layers we're down */
hendrikvincent 0:05ccbd4f84f1 298 }
hendrikvincent 0:05ccbd4f84f1 299 /* Init restart counter, send Terminate-Request */
hendrikvincent 0:05ccbd4f84f1 300 f->retransmits = f->maxtermtransmits;
hendrikvincent 0:05ccbd4f84f1 301 fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
hendrikvincent 0:05ccbd4f84f1 302 (u_char *) f->term_reason, f->term_reason_len);
hendrikvincent 0:05ccbd4f84f1 303 TIMEOUT(fsm_timeout, f, f->timeouttime);
hendrikvincent 0:05ccbd4f84f1 304 --f->retransmits;
hendrikvincent 0:05ccbd4f84f1 305
hendrikvincent 0:05ccbd4f84f1 306 f->state = LS_CLOSING;
hendrikvincent 0:05ccbd4f84f1 307 break;
hendrikvincent 0:05ccbd4f84f1 308 }
hendrikvincent 0:05ccbd4f84f1 309
hendrikvincent 0:05ccbd4f84f1 310 FSMDEBUG(LOG_INFO, ("%s: close reason=%s state %d (%s) -> %d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 311 PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 312 }
hendrikvincent 0:05ccbd4f84f1 313
hendrikvincent 0:05ccbd4f84f1 314
hendrikvincent 0:05ccbd4f84f1 315 /*
hendrikvincent 0:05ccbd4f84f1 316 * fsm_timeout - Timeout expired.
hendrikvincent 0:05ccbd4f84f1 317 */
hendrikvincent 0:05ccbd4f84f1 318 static void
hendrikvincent 0:05ccbd4f84f1 319 fsm_timeout(void *arg)
hendrikvincent 0:05ccbd4f84f1 320 {
hendrikvincent 0:05ccbd4f84f1 321 fsm *f = (fsm *) arg;
hendrikvincent 0:05ccbd4f84f1 322
hendrikvincent 0:05ccbd4f84f1 323 switch (f->state) {
hendrikvincent 0:05ccbd4f84f1 324 case LS_CLOSING:
hendrikvincent 0:05ccbd4f84f1 325 case LS_STOPPING:
hendrikvincent 0:05ccbd4f84f1 326 if( f->retransmits <= 0 ) {
hendrikvincent 0:05ccbd4f84f1 327 FSMDEBUG(LOG_WARNING, ("%s: timeout sending Terminate-Request state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 328 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 329 /*
hendrikvincent 0:05ccbd4f84f1 330 * We've waited for an ack long enough. Peer probably heard us.
hendrikvincent 0:05ccbd4f84f1 331 */
hendrikvincent 0:05ccbd4f84f1 332 f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED;
hendrikvincent 0:05ccbd4f84f1 333 if( f->callbacks->finished ) {
hendrikvincent 0:05ccbd4f84f1 334 (*f->callbacks->finished)(f);
hendrikvincent 0:05ccbd4f84f1 335 }
hendrikvincent 0:05ccbd4f84f1 336 } else {
hendrikvincent 0:05ccbd4f84f1 337 FSMDEBUG(LOG_WARNING, ("%s: timeout resending Terminate-Requests state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 338 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 339 /* Send Terminate-Request */
hendrikvincent 0:05ccbd4f84f1 340 fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
hendrikvincent 0:05ccbd4f84f1 341 (u_char *) f->term_reason, f->term_reason_len);
hendrikvincent 0:05ccbd4f84f1 342 TIMEOUT(fsm_timeout, f, f->timeouttime);
hendrikvincent 0:05ccbd4f84f1 343 --f->retransmits;
hendrikvincent 0:05ccbd4f84f1 344 }
hendrikvincent 0:05ccbd4f84f1 345 break;
hendrikvincent 0:05ccbd4f84f1 346
hendrikvincent 0:05ccbd4f84f1 347 case LS_REQSENT:
hendrikvincent 0:05ccbd4f84f1 348 case LS_ACKRCVD:
hendrikvincent 0:05ccbd4f84f1 349 case LS_ACKSENT:
hendrikvincent 0:05ccbd4f84f1 350 if (f->retransmits <= 0) {
hendrikvincent 0:05ccbd4f84f1 351 FSMDEBUG(LOG_WARNING, ("%s: timeout sending Config-Requests state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 352 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 353 f->state = LS_STOPPED;
hendrikvincent 0:05ccbd4f84f1 354 if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) {
hendrikvincent 0:05ccbd4f84f1 355 (*f->callbacks->finished)(f);
hendrikvincent 0:05ccbd4f84f1 356 }
hendrikvincent 0:05ccbd4f84f1 357 } else {
hendrikvincent 0:05ccbd4f84f1 358 FSMDEBUG(LOG_WARNING, ("%s: timeout resending Config-Request state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 359 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 360 /* Retransmit the configure-request */
hendrikvincent 0:05ccbd4f84f1 361 if (f->callbacks->retransmit) {
hendrikvincent 0:05ccbd4f84f1 362 (*f->callbacks->retransmit)(f);
hendrikvincent 0:05ccbd4f84f1 363 }
hendrikvincent 0:05ccbd4f84f1 364 fsm_sconfreq(f, 1); /* Re-send Configure-Request */
hendrikvincent 0:05ccbd4f84f1 365 if( f->state == LS_ACKRCVD ) {
hendrikvincent 0:05ccbd4f84f1 366 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 367 }
hendrikvincent 0:05ccbd4f84f1 368 }
hendrikvincent 0:05ccbd4f84f1 369 break;
hendrikvincent 0:05ccbd4f84f1 370
hendrikvincent 0:05ccbd4f84f1 371 default:
hendrikvincent 0:05ccbd4f84f1 372 FSMDEBUG(LOG_INFO, ("%s: UNHANDLED timeout event in state %d (%s)!\n",
hendrikvincent 0:05ccbd4f84f1 373 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 374 }
hendrikvincent 0:05ccbd4f84f1 375 }
hendrikvincent 0:05ccbd4f84f1 376
hendrikvincent 0:05ccbd4f84f1 377
hendrikvincent 0:05ccbd4f84f1 378 /*
hendrikvincent 0:05ccbd4f84f1 379 * fsm_input - Input packet.
hendrikvincent 0:05ccbd4f84f1 380 */
hendrikvincent 0:05ccbd4f84f1 381 void
hendrikvincent 0:05ccbd4f84f1 382 fsm_input(fsm *f, u_char *inpacket, int l)
hendrikvincent 0:05ccbd4f84f1 383 {
hendrikvincent 0:05ccbd4f84f1 384 u_char *inp = inpacket;
hendrikvincent 0:05ccbd4f84f1 385 u_char code, id;
hendrikvincent 0:05ccbd4f84f1 386 int len;
hendrikvincent 0:05ccbd4f84f1 387
hendrikvincent 0:05ccbd4f84f1 388 /*
hendrikvincent 0:05ccbd4f84f1 389 * Parse header (code, id and length).
hendrikvincent 0:05ccbd4f84f1 390 * If packet too short, drop it.
hendrikvincent 0:05ccbd4f84f1 391 */
hendrikvincent 0:05ccbd4f84f1 392 if (l < HEADERLEN) {
hendrikvincent 0:05ccbd4f84f1 393 FSMDEBUG(LOG_WARNING, ("fsm_input(%x): Rcvd short header.\n",
hendrikvincent 0:05ccbd4f84f1 394 f->protocol));
hendrikvincent 0:05ccbd4f84f1 395 return;
hendrikvincent 0:05ccbd4f84f1 396 }
hendrikvincent 0:05ccbd4f84f1 397 GETCHAR(code, inp);
hendrikvincent 0:05ccbd4f84f1 398 GETCHAR(id, inp);
hendrikvincent 0:05ccbd4f84f1 399 GETSHORT(len, inp);
hendrikvincent 0:05ccbd4f84f1 400 if (len < HEADERLEN) {
hendrikvincent 0:05ccbd4f84f1 401 FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd illegal length.\n",
hendrikvincent 0:05ccbd4f84f1 402 f->protocol));
hendrikvincent 0:05ccbd4f84f1 403 return;
hendrikvincent 0:05ccbd4f84f1 404 }
hendrikvincent 0:05ccbd4f84f1 405 if (len > l) {
hendrikvincent 0:05ccbd4f84f1 406 FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd short packet.\n",
hendrikvincent 0:05ccbd4f84f1 407 f->protocol));
hendrikvincent 0:05ccbd4f84f1 408 return;
hendrikvincent 0:05ccbd4f84f1 409 }
hendrikvincent 0:05ccbd4f84f1 410 len -= HEADERLEN; /* subtract header length */
hendrikvincent 0:05ccbd4f84f1 411
hendrikvincent 0:05ccbd4f84f1 412 if( f->state == LS_INITIAL || f->state == LS_STARTING ) {
hendrikvincent 0:05ccbd4f84f1 413 FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd packet in state %d (%s).\n",
hendrikvincent 0:05ccbd4f84f1 414 f->protocol, f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 415 return;
hendrikvincent 0:05ccbd4f84f1 416 }
hendrikvincent 0:05ccbd4f84f1 417 FSMDEBUG(LOG_INFO, ("fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));
hendrikvincent 0:05ccbd4f84f1 418 /*
hendrikvincent 0:05ccbd4f84f1 419 * Action depends on code.
hendrikvincent 0:05ccbd4f84f1 420 */
hendrikvincent 0:05ccbd4f84f1 421 switch (code) {
hendrikvincent 0:05ccbd4f84f1 422 case CONFREQ:
hendrikvincent 0:05ccbd4f84f1 423 fsm_rconfreq(f, id, inp, len);
hendrikvincent 0:05ccbd4f84f1 424 break;
hendrikvincent 0:05ccbd4f84f1 425
hendrikvincent 0:05ccbd4f84f1 426 case CONFACK:
hendrikvincent 0:05ccbd4f84f1 427 fsm_rconfack(f, id, inp, len);
hendrikvincent 0:05ccbd4f84f1 428 break;
hendrikvincent 0:05ccbd4f84f1 429
hendrikvincent 0:05ccbd4f84f1 430 case CONFNAK:
hendrikvincent 0:05ccbd4f84f1 431 case CONFREJ:
hendrikvincent 0:05ccbd4f84f1 432 fsm_rconfnakrej(f, code, id, inp, len);
hendrikvincent 0:05ccbd4f84f1 433 break;
hendrikvincent 0:05ccbd4f84f1 434
hendrikvincent 0:05ccbd4f84f1 435 case TERMREQ:
hendrikvincent 0:05ccbd4f84f1 436 fsm_rtermreq(f, id, inp, len);
hendrikvincent 0:05ccbd4f84f1 437 break;
hendrikvincent 0:05ccbd4f84f1 438
hendrikvincent 0:05ccbd4f84f1 439 case TERMACK:
hendrikvincent 0:05ccbd4f84f1 440 fsm_rtermack(f);
hendrikvincent 0:05ccbd4f84f1 441 break;
hendrikvincent 0:05ccbd4f84f1 442
hendrikvincent 0:05ccbd4f84f1 443 case CODEREJ:
hendrikvincent 0:05ccbd4f84f1 444 fsm_rcoderej(f, inp, len);
hendrikvincent 0:05ccbd4f84f1 445 break;
hendrikvincent 0:05ccbd4f84f1 446
hendrikvincent 0:05ccbd4f84f1 447 default:
hendrikvincent 0:05ccbd4f84f1 448 FSMDEBUG(LOG_INFO, ("fsm_input(%s): default: \n", PROTO_NAME(f)));
hendrikvincent 0:05ccbd4f84f1 449 if( !f->callbacks->extcode ||
hendrikvincent 0:05ccbd4f84f1 450 !(*f->callbacks->extcode)(f, code, id, inp, len) ) {
hendrikvincent 0:05ccbd4f84f1 451 fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
hendrikvincent 0:05ccbd4f84f1 452 }
hendrikvincent 0:05ccbd4f84f1 453 break;
hendrikvincent 0:05ccbd4f84f1 454 }
hendrikvincent 0:05ccbd4f84f1 455 }
hendrikvincent 0:05ccbd4f84f1 456
hendrikvincent 0:05ccbd4f84f1 457
hendrikvincent 0:05ccbd4f84f1 458 /*
hendrikvincent 0:05ccbd4f84f1 459 * fsm_rconfreq - Receive Configure-Request.
hendrikvincent 0:05ccbd4f84f1 460 */
hendrikvincent 0:05ccbd4f84f1 461 static void
hendrikvincent 0:05ccbd4f84f1 462 fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)
hendrikvincent 0:05ccbd4f84f1 463 {
hendrikvincent 0:05ccbd4f84f1 464 int code, reject_if_disagree;
hendrikvincent 0:05ccbd4f84f1 465
hendrikvincent 0:05ccbd4f84f1 466 FSMDEBUG(LOG_INFO, ("fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 467 PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 468 switch( f->state ) {
hendrikvincent 0:05ccbd4f84f1 469 case LS_CLOSED:
hendrikvincent 0:05ccbd4f84f1 470 /* Go away, we're closed */
hendrikvincent 0:05ccbd4f84f1 471 fsm_sdata(f, TERMACK, id, NULL, 0);
hendrikvincent 0:05ccbd4f84f1 472 return;
hendrikvincent 0:05ccbd4f84f1 473 case LS_CLOSING:
hendrikvincent 0:05ccbd4f84f1 474 case LS_STOPPING:
hendrikvincent 0:05ccbd4f84f1 475 return;
hendrikvincent 0:05ccbd4f84f1 476
hendrikvincent 0:05ccbd4f84f1 477 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 478 /* Go down and restart negotiation */
hendrikvincent 0:05ccbd4f84f1 479 if( f->callbacks->down ) {
hendrikvincent 0:05ccbd4f84f1 480 (*f->callbacks->down)(f); /* Inform upper layers */
hendrikvincent 0:05ccbd4f84f1 481 }
hendrikvincent 0:05ccbd4f84f1 482 fsm_sconfreq(f, 0); /* Send initial Configure-Request */
hendrikvincent 0:05ccbd4f84f1 483 break;
hendrikvincent 0:05ccbd4f84f1 484
hendrikvincent 0:05ccbd4f84f1 485 case LS_STOPPED:
hendrikvincent 0:05ccbd4f84f1 486 /* Negotiation started by our peer */
hendrikvincent 0:05ccbd4f84f1 487 fsm_sconfreq(f, 0); /* Send initial Configure-Request */
hendrikvincent 0:05ccbd4f84f1 488 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 489 break;
hendrikvincent 0:05ccbd4f84f1 490 }
hendrikvincent 0:05ccbd4f84f1 491
hendrikvincent 0:05ccbd4f84f1 492 /*
hendrikvincent 0:05ccbd4f84f1 493 * Pass the requested configuration options
hendrikvincent 0:05ccbd4f84f1 494 * to protocol-specific code for checking.
hendrikvincent 0:05ccbd4f84f1 495 */
hendrikvincent 0:05ccbd4f84f1 496 if (f->callbacks->reqci) { /* Check CI */
hendrikvincent 0:05ccbd4f84f1 497 reject_if_disagree = (f->nakloops >= f->maxnakloops);
hendrikvincent 0:05ccbd4f84f1 498 code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
hendrikvincent 0:05ccbd4f84f1 499 } else if (len) {
hendrikvincent 0:05ccbd4f84f1 500 code = CONFREJ; /* Reject all CI */
hendrikvincent 0:05ccbd4f84f1 501 } else {
hendrikvincent 0:05ccbd4f84f1 502 code = CONFACK;
hendrikvincent 0:05ccbd4f84f1 503 }
hendrikvincent 0:05ccbd4f84f1 504
hendrikvincent 0:05ccbd4f84f1 505 /* send the Ack, Nak or Rej to the peer */
hendrikvincent 0:05ccbd4f84f1 506 fsm_sdata(f, (u_char)code, id, inp, len);
hendrikvincent 0:05ccbd4f84f1 507
hendrikvincent 0:05ccbd4f84f1 508 if (code == CONFACK) {
hendrikvincent 0:05ccbd4f84f1 509 if (f->state == LS_ACKRCVD) {
hendrikvincent 0:05ccbd4f84f1 510 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 511 f->state = LS_OPENED;
hendrikvincent 0:05ccbd4f84f1 512 if (f->callbacks->up) {
hendrikvincent 0:05ccbd4f84f1 513 (*f->callbacks->up)(f); /* Inform upper layers */
hendrikvincent 0:05ccbd4f84f1 514 }
hendrikvincent 0:05ccbd4f84f1 515 } else {
hendrikvincent 0:05ccbd4f84f1 516 f->state = LS_ACKSENT;
hendrikvincent 0:05ccbd4f84f1 517 }
hendrikvincent 0:05ccbd4f84f1 518 f->nakloops = 0;
hendrikvincent 0:05ccbd4f84f1 519 } else {
hendrikvincent 0:05ccbd4f84f1 520 /* we sent CONFACK or CONFREJ */
hendrikvincent 0:05ccbd4f84f1 521 if (f->state != LS_ACKRCVD) {
hendrikvincent 0:05ccbd4f84f1 522 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 523 }
hendrikvincent 0:05ccbd4f84f1 524 if( code == CONFNAK ) {
hendrikvincent 0:05ccbd4f84f1 525 ++f->nakloops;
hendrikvincent 0:05ccbd4f84f1 526 }
hendrikvincent 0:05ccbd4f84f1 527 }
hendrikvincent 0:05ccbd4f84f1 528 }
hendrikvincent 0:05ccbd4f84f1 529
hendrikvincent 0:05ccbd4f84f1 530
hendrikvincent 0:05ccbd4f84f1 531 /*
hendrikvincent 0:05ccbd4f84f1 532 * fsm_rconfack - Receive Configure-Ack.
hendrikvincent 0:05ccbd4f84f1 533 */
hendrikvincent 0:05ccbd4f84f1 534 static void
hendrikvincent 0:05ccbd4f84f1 535 fsm_rconfack(fsm *f, int id, u_char *inp, int len)
hendrikvincent 0:05ccbd4f84f1 536 {
hendrikvincent 0:05ccbd4f84f1 537 FSMDEBUG(LOG_INFO, ("fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 538 PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 539
hendrikvincent 0:05ccbd4f84f1 540 if (id != f->reqid || f->seen_ack) { /* Expected id? */
hendrikvincent 0:05ccbd4f84f1 541 return; /* Nope, toss... */
hendrikvincent 0:05ccbd4f84f1 542 }
hendrikvincent 0:05ccbd4f84f1 543 if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ) {
hendrikvincent 0:05ccbd4f84f1 544 /* Ack is bad - ignore it */
hendrikvincent 0:05ccbd4f84f1 545 FSMDEBUG(LOG_INFO, ("%s: received bad Ack (length %d)\n",
hendrikvincent 0:05ccbd4f84f1 546 PROTO_NAME(f), len));
hendrikvincent 0:05ccbd4f84f1 547 return;
hendrikvincent 0:05ccbd4f84f1 548 }
hendrikvincent 0:05ccbd4f84f1 549 f->seen_ack = 1;
hendrikvincent 0:05ccbd4f84f1 550
hendrikvincent 0:05ccbd4f84f1 551 switch (f->state) {
hendrikvincent 0:05ccbd4f84f1 552 case LS_CLOSED:
hendrikvincent 0:05ccbd4f84f1 553 case LS_STOPPED:
hendrikvincent 0:05ccbd4f84f1 554 fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
hendrikvincent 0:05ccbd4f84f1 555 break;
hendrikvincent 0:05ccbd4f84f1 556
hendrikvincent 0:05ccbd4f84f1 557 case LS_REQSENT:
hendrikvincent 0:05ccbd4f84f1 558 f->state = LS_ACKRCVD;
hendrikvincent 0:05ccbd4f84f1 559 f->retransmits = f->maxconfreqtransmits;
hendrikvincent 0:05ccbd4f84f1 560 break;
hendrikvincent 0:05ccbd4f84f1 561
hendrikvincent 0:05ccbd4f84f1 562 case LS_ACKRCVD:
hendrikvincent 0:05ccbd4f84f1 563 /* Huh? an extra valid Ack? oh well... */
hendrikvincent 0:05ccbd4f84f1 564 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 565 fsm_sconfreq(f, 0);
hendrikvincent 0:05ccbd4f84f1 566 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 567 break;
hendrikvincent 0:05ccbd4f84f1 568
hendrikvincent 0:05ccbd4f84f1 569 case LS_ACKSENT:
hendrikvincent 0:05ccbd4f84f1 570 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 571 f->state = LS_OPENED;
hendrikvincent 0:05ccbd4f84f1 572 f->retransmits = f->maxconfreqtransmits;
hendrikvincent 0:05ccbd4f84f1 573 if (f->callbacks->up) {
hendrikvincent 0:05ccbd4f84f1 574 (*f->callbacks->up)(f); /* Inform upper layers */
hendrikvincent 0:05ccbd4f84f1 575 }
hendrikvincent 0:05ccbd4f84f1 576 break;
hendrikvincent 0:05ccbd4f84f1 577
hendrikvincent 0:05ccbd4f84f1 578 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 579 /* Go down and restart negotiation */
hendrikvincent 0:05ccbd4f84f1 580 if (f->callbacks->down) {
hendrikvincent 0:05ccbd4f84f1 581 (*f->callbacks->down)(f); /* Inform upper layers */
hendrikvincent 0:05ccbd4f84f1 582 }
hendrikvincent 0:05ccbd4f84f1 583 fsm_sconfreq(f, 0); /* Send initial Configure-Request */
hendrikvincent 0:05ccbd4f84f1 584 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 585 break;
hendrikvincent 0:05ccbd4f84f1 586 }
hendrikvincent 0:05ccbd4f84f1 587 }
hendrikvincent 0:05ccbd4f84f1 588
hendrikvincent 0:05ccbd4f84f1 589
hendrikvincent 0:05ccbd4f84f1 590 /*
hendrikvincent 0:05ccbd4f84f1 591 * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
hendrikvincent 0:05ccbd4f84f1 592 */
hendrikvincent 0:05ccbd4f84f1 593 static void
hendrikvincent 0:05ccbd4f84f1 594 fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
hendrikvincent 0:05ccbd4f84f1 595 {
hendrikvincent 0:05ccbd4f84f1 596 int (*proc) (fsm *, u_char *, int);
hendrikvincent 0:05ccbd4f84f1 597 int ret;
hendrikvincent 0:05ccbd4f84f1 598
hendrikvincent 0:05ccbd4f84f1 599 FSMDEBUG(LOG_INFO, ("fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 600 PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 601
hendrikvincent 0:05ccbd4f84f1 602 if (id != f->reqid || f->seen_ack) { /* Expected id? */
hendrikvincent 0:05ccbd4f84f1 603 return; /* Nope, toss... */
hendrikvincent 0:05ccbd4f84f1 604 }
hendrikvincent 0:05ccbd4f84f1 605 proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
hendrikvincent 0:05ccbd4f84f1 606 if (!proc || !((ret = proc(f, inp, len)))) {
hendrikvincent 0:05ccbd4f84f1 607 /* Nak/reject is bad - ignore it */
hendrikvincent 0:05ccbd4f84f1 608 FSMDEBUG(LOG_INFO, ("%s: received bad %s (length %d)\n",
hendrikvincent 0:05ccbd4f84f1 609 PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
hendrikvincent 0:05ccbd4f84f1 610 return;
hendrikvincent 0:05ccbd4f84f1 611 }
hendrikvincent 0:05ccbd4f84f1 612 f->seen_ack = 1;
hendrikvincent 0:05ccbd4f84f1 613
hendrikvincent 0:05ccbd4f84f1 614 switch (f->state) {
hendrikvincent 0:05ccbd4f84f1 615 case LS_CLOSED:
hendrikvincent 0:05ccbd4f84f1 616 case LS_STOPPED:
hendrikvincent 0:05ccbd4f84f1 617 fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
hendrikvincent 0:05ccbd4f84f1 618 break;
hendrikvincent 0:05ccbd4f84f1 619
hendrikvincent 0:05ccbd4f84f1 620 case LS_REQSENT:
hendrikvincent 0:05ccbd4f84f1 621 case LS_ACKSENT:
hendrikvincent 0:05ccbd4f84f1 622 /* They didn't agree to what we wanted - try another request */
hendrikvincent 0:05ccbd4f84f1 623 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 624 if (ret < 0) {
hendrikvincent 0:05ccbd4f84f1 625 f->state = LS_STOPPED; /* kludge for stopping CCP */
hendrikvincent 0:05ccbd4f84f1 626 } else {
hendrikvincent 0:05ccbd4f84f1 627 fsm_sconfreq(f, 0); /* Send Configure-Request */
hendrikvincent 0:05ccbd4f84f1 628 }
hendrikvincent 0:05ccbd4f84f1 629 break;
hendrikvincent 0:05ccbd4f84f1 630
hendrikvincent 0:05ccbd4f84f1 631 case LS_ACKRCVD:
hendrikvincent 0:05ccbd4f84f1 632 /* Got a Nak/reject when we had already had an Ack?? oh well... */
hendrikvincent 0:05ccbd4f84f1 633 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 634 fsm_sconfreq(f, 0);
hendrikvincent 0:05ccbd4f84f1 635 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 636 break;
hendrikvincent 0:05ccbd4f84f1 637
hendrikvincent 0:05ccbd4f84f1 638 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 639 /* Go down and restart negotiation */
hendrikvincent 0:05ccbd4f84f1 640 if (f->callbacks->down) {
hendrikvincent 0:05ccbd4f84f1 641 (*f->callbacks->down)(f); /* Inform upper layers */
hendrikvincent 0:05ccbd4f84f1 642 }
hendrikvincent 0:05ccbd4f84f1 643 fsm_sconfreq(f, 0); /* Send initial Configure-Request */
hendrikvincent 0:05ccbd4f84f1 644 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 645 break;
hendrikvincent 0:05ccbd4f84f1 646 }
hendrikvincent 0:05ccbd4f84f1 647 }
hendrikvincent 0:05ccbd4f84f1 648
hendrikvincent 0:05ccbd4f84f1 649
hendrikvincent 0:05ccbd4f84f1 650 /*
hendrikvincent 0:05ccbd4f84f1 651 * fsm_rtermreq - Receive Terminate-Req.
hendrikvincent 0:05ccbd4f84f1 652 */
hendrikvincent 0:05ccbd4f84f1 653 static void
hendrikvincent 0:05ccbd4f84f1 654 fsm_rtermreq(fsm *f, int id, u_char *p, int len)
hendrikvincent 0:05ccbd4f84f1 655 {
hendrikvincent 0:05ccbd4f84f1 656 LWIP_UNUSED_ARG(p);
hendrikvincent 0:05ccbd4f84f1 657
hendrikvincent 0:05ccbd4f84f1 658 FSMDEBUG(LOG_INFO, ("fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 659 PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 660
hendrikvincent 0:05ccbd4f84f1 661 switch (f->state) {
hendrikvincent 0:05ccbd4f84f1 662 case LS_ACKRCVD:
hendrikvincent 0:05ccbd4f84f1 663 case LS_ACKSENT:
hendrikvincent 0:05ccbd4f84f1 664 f->state = LS_REQSENT; /* Start over but keep trying */
hendrikvincent 0:05ccbd4f84f1 665 break;
hendrikvincent 0:05ccbd4f84f1 666
hendrikvincent 0:05ccbd4f84f1 667 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 668 if (len > 0) {
hendrikvincent 0:05ccbd4f84f1 669 FSMDEBUG(LOG_INFO, ("%s terminated by peer (%p)\n", PROTO_NAME(f), p));
hendrikvincent 0:05ccbd4f84f1 670 } else {
hendrikvincent 0:05ccbd4f84f1 671 FSMDEBUG(LOG_INFO, ("%s terminated by peer\n", PROTO_NAME(f)));
hendrikvincent 0:05ccbd4f84f1 672 }
hendrikvincent 0:05ccbd4f84f1 673 if (f->callbacks->down) {
hendrikvincent 0:05ccbd4f84f1 674 (*f->callbacks->down)(f); /* Inform upper layers */
hendrikvincent 0:05ccbd4f84f1 675 }
hendrikvincent 0:05ccbd4f84f1 676 f->retransmits = 0;
hendrikvincent 0:05ccbd4f84f1 677 f->state = LS_STOPPING;
hendrikvincent 0:05ccbd4f84f1 678 TIMEOUT(fsm_timeout, f, f->timeouttime);
hendrikvincent 0:05ccbd4f84f1 679 break;
hendrikvincent 0:05ccbd4f84f1 680 }
hendrikvincent 0:05ccbd4f84f1 681
hendrikvincent 0:05ccbd4f84f1 682 fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
hendrikvincent 0:05ccbd4f84f1 683 }
hendrikvincent 0:05ccbd4f84f1 684
hendrikvincent 0:05ccbd4f84f1 685
hendrikvincent 0:05ccbd4f84f1 686 /*
hendrikvincent 0:05ccbd4f84f1 687 * fsm_rtermack - Receive Terminate-Ack.
hendrikvincent 0:05ccbd4f84f1 688 */
hendrikvincent 0:05ccbd4f84f1 689 static void
hendrikvincent 0:05ccbd4f84f1 690 fsm_rtermack(fsm *f)
hendrikvincent 0:05ccbd4f84f1 691 {
hendrikvincent 0:05ccbd4f84f1 692 FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 693 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 694
hendrikvincent 0:05ccbd4f84f1 695 switch (f->state) {
hendrikvincent 0:05ccbd4f84f1 696 case LS_CLOSING:
hendrikvincent 0:05ccbd4f84f1 697 UNTIMEOUT(fsm_timeout, f);
hendrikvincent 0:05ccbd4f84f1 698 f->state = LS_CLOSED;
hendrikvincent 0:05ccbd4f84f1 699 if( f->callbacks->finished ) {
hendrikvincent 0:05ccbd4f84f1 700 (*f->callbacks->finished)(f);
hendrikvincent 0:05ccbd4f84f1 701 }
hendrikvincent 0:05ccbd4f84f1 702 break;
hendrikvincent 0:05ccbd4f84f1 703
hendrikvincent 0:05ccbd4f84f1 704 case LS_STOPPING:
hendrikvincent 0:05ccbd4f84f1 705 UNTIMEOUT(fsm_timeout, f);
hendrikvincent 0:05ccbd4f84f1 706 f->state = LS_STOPPED;
hendrikvincent 0:05ccbd4f84f1 707 if( f->callbacks->finished ) {
hendrikvincent 0:05ccbd4f84f1 708 (*f->callbacks->finished)(f);
hendrikvincent 0:05ccbd4f84f1 709 }
hendrikvincent 0:05ccbd4f84f1 710 break;
hendrikvincent 0:05ccbd4f84f1 711
hendrikvincent 0:05ccbd4f84f1 712 case LS_ACKRCVD:
hendrikvincent 0:05ccbd4f84f1 713 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 714 break;
hendrikvincent 0:05ccbd4f84f1 715
hendrikvincent 0:05ccbd4f84f1 716 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 717 if (f->callbacks->down) {
hendrikvincent 0:05ccbd4f84f1 718 (*f->callbacks->down)(f); /* Inform upper layers */
hendrikvincent 0:05ccbd4f84f1 719 }
hendrikvincent 0:05ccbd4f84f1 720 fsm_sconfreq(f, 0);
hendrikvincent 0:05ccbd4f84f1 721 break;
hendrikvincent 0:05ccbd4f84f1 722 default:
hendrikvincent 0:05ccbd4f84f1 723 FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): UNHANDLED state=%d (%s)!!!\n",
hendrikvincent 0:05ccbd4f84f1 724 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 725 }
hendrikvincent 0:05ccbd4f84f1 726 }
hendrikvincent 0:05ccbd4f84f1 727
hendrikvincent 0:05ccbd4f84f1 728
hendrikvincent 0:05ccbd4f84f1 729 /*
hendrikvincent 0:05ccbd4f84f1 730 * fsm_rcoderej - Receive an Code-Reject.
hendrikvincent 0:05ccbd4f84f1 731 */
hendrikvincent 0:05ccbd4f84f1 732 static void
hendrikvincent 0:05ccbd4f84f1 733 fsm_rcoderej(fsm *f, u_char *inp, int len)
hendrikvincent 0:05ccbd4f84f1 734 {
hendrikvincent 0:05ccbd4f84f1 735 u_char code, id;
hendrikvincent 0:05ccbd4f84f1 736
hendrikvincent 0:05ccbd4f84f1 737 FSMDEBUG(LOG_INFO, ("fsm_rcoderej(%s): state=%d (%s)\n",
hendrikvincent 0:05ccbd4f84f1 738 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 739
hendrikvincent 0:05ccbd4f84f1 740 if (len < HEADERLEN) {
hendrikvincent 0:05ccbd4f84f1 741 FSMDEBUG(LOG_INFO, ("fsm_rcoderej: Rcvd short Code-Reject packet!\n"));
hendrikvincent 0:05ccbd4f84f1 742 return;
hendrikvincent 0:05ccbd4f84f1 743 }
hendrikvincent 0:05ccbd4f84f1 744 GETCHAR(code, inp);
hendrikvincent 0:05ccbd4f84f1 745 GETCHAR(id, inp);
hendrikvincent 0:05ccbd4f84f1 746 FSMDEBUG(LOG_WARNING, ("%s: Rcvd Code-Reject for code %d, id %d\n",
hendrikvincent 0:05ccbd4f84f1 747 PROTO_NAME(f), code, id));
hendrikvincent 0:05ccbd4f84f1 748
hendrikvincent 0:05ccbd4f84f1 749 if( f->state == LS_ACKRCVD ) {
hendrikvincent 0:05ccbd4f84f1 750 f->state = LS_REQSENT;
hendrikvincent 0:05ccbd4f84f1 751 }
hendrikvincent 0:05ccbd4f84f1 752 }
hendrikvincent 0:05ccbd4f84f1 753
hendrikvincent 0:05ccbd4f84f1 754
hendrikvincent 0:05ccbd4f84f1 755 /*
hendrikvincent 0:05ccbd4f84f1 756 * fsm_protreject - Peer doesn't speak this protocol.
hendrikvincent 0:05ccbd4f84f1 757 *
hendrikvincent 0:05ccbd4f84f1 758 * Treat this as a catastrophic error (RXJ-).
hendrikvincent 0:05ccbd4f84f1 759 */
hendrikvincent 0:05ccbd4f84f1 760 void
hendrikvincent 0:05ccbd4f84f1 761 fsm_protreject(fsm *f)
hendrikvincent 0:05ccbd4f84f1 762 {
hendrikvincent 0:05ccbd4f84f1 763 switch( f->state ) {
hendrikvincent 0:05ccbd4f84f1 764 case LS_CLOSING:
hendrikvincent 0:05ccbd4f84f1 765 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 766 /* fall through */
hendrikvincent 0:05ccbd4f84f1 767 case LS_CLOSED:
hendrikvincent 0:05ccbd4f84f1 768 f->state = LS_CLOSED;
hendrikvincent 0:05ccbd4f84f1 769 if( f->callbacks->finished ) {
hendrikvincent 0:05ccbd4f84f1 770 (*f->callbacks->finished)(f);
hendrikvincent 0:05ccbd4f84f1 771 }
hendrikvincent 0:05ccbd4f84f1 772 break;
hendrikvincent 0:05ccbd4f84f1 773
hendrikvincent 0:05ccbd4f84f1 774 case LS_STOPPING:
hendrikvincent 0:05ccbd4f84f1 775 case LS_REQSENT:
hendrikvincent 0:05ccbd4f84f1 776 case LS_ACKRCVD:
hendrikvincent 0:05ccbd4f84f1 777 case LS_ACKSENT:
hendrikvincent 0:05ccbd4f84f1 778 UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
hendrikvincent 0:05ccbd4f84f1 779 /* fall through */
hendrikvincent 0:05ccbd4f84f1 780 case LS_STOPPED:
hendrikvincent 0:05ccbd4f84f1 781 f->state = LS_STOPPED;
hendrikvincent 0:05ccbd4f84f1 782 if( f->callbacks->finished ) {
hendrikvincent 0:05ccbd4f84f1 783 (*f->callbacks->finished)(f);
hendrikvincent 0:05ccbd4f84f1 784 }
hendrikvincent 0:05ccbd4f84f1 785 break;
hendrikvincent 0:05ccbd4f84f1 786
hendrikvincent 0:05ccbd4f84f1 787 case LS_OPENED:
hendrikvincent 0:05ccbd4f84f1 788 if( f->callbacks->down ) {
hendrikvincent 0:05ccbd4f84f1 789 (*f->callbacks->down)(f);
hendrikvincent 0:05ccbd4f84f1 790 }
hendrikvincent 0:05ccbd4f84f1 791 /* Init restart counter, send Terminate-Request */
hendrikvincent 0:05ccbd4f84f1 792 f->retransmits = f->maxtermtransmits;
hendrikvincent 0:05ccbd4f84f1 793 fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
hendrikvincent 0:05ccbd4f84f1 794 (u_char *) f->term_reason, f->term_reason_len);
hendrikvincent 0:05ccbd4f84f1 795 TIMEOUT(fsm_timeout, f, f->timeouttime);
hendrikvincent 0:05ccbd4f84f1 796 --f->retransmits;
hendrikvincent 0:05ccbd4f84f1 797
hendrikvincent 0:05ccbd4f84f1 798 f->state = LS_STOPPING;
hendrikvincent 0:05ccbd4f84f1 799 break;
hendrikvincent 0:05ccbd4f84f1 800
hendrikvincent 0:05ccbd4f84f1 801 default:
hendrikvincent 0:05ccbd4f84f1 802 FSMDEBUG(LOG_INFO, ("%s: Protocol-reject event in state %d (%s)!\n",
hendrikvincent 0:05ccbd4f84f1 803 PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
hendrikvincent 0:05ccbd4f84f1 804 }
hendrikvincent 0:05ccbd4f84f1 805 }
hendrikvincent 0:05ccbd4f84f1 806
hendrikvincent 0:05ccbd4f84f1 807
hendrikvincent 0:05ccbd4f84f1 808 /*
hendrikvincent 0:05ccbd4f84f1 809 * fsm_sconfreq - Send a Configure-Request.
hendrikvincent 0:05ccbd4f84f1 810 */
hendrikvincent 0:05ccbd4f84f1 811 static void
hendrikvincent 0:05ccbd4f84f1 812 fsm_sconfreq(fsm *f, int retransmit)
hendrikvincent 0:05ccbd4f84f1 813 {
hendrikvincent 0:05ccbd4f84f1 814 u_char *outp;
hendrikvincent 0:05ccbd4f84f1 815 int cilen;
hendrikvincent 0:05ccbd4f84f1 816
hendrikvincent 0:05ccbd4f84f1 817 if( f->state != LS_REQSENT && f->state != LS_ACKRCVD && f->state != LS_ACKSENT ) {
hendrikvincent 0:05ccbd4f84f1 818 /* Not currently negotiating - reset options */
hendrikvincent 0:05ccbd4f84f1 819 if( f->callbacks->resetci ) {
hendrikvincent 0:05ccbd4f84f1 820 (*f->callbacks->resetci)(f);
hendrikvincent 0:05ccbd4f84f1 821 }
hendrikvincent 0:05ccbd4f84f1 822 f->nakloops = 0;
hendrikvincent 0:05ccbd4f84f1 823 }
hendrikvincent 0:05ccbd4f84f1 824
hendrikvincent 0:05ccbd4f84f1 825 if( !retransmit ) {
hendrikvincent 0:05ccbd4f84f1 826 /* New request - reset retransmission counter, use new ID */
hendrikvincent 0:05ccbd4f84f1 827 f->retransmits = f->maxconfreqtransmits;
hendrikvincent 0:05ccbd4f84f1 828 f->reqid = ++f->id;
hendrikvincent 0:05ccbd4f84f1 829 }
hendrikvincent 0:05ccbd4f84f1 830
hendrikvincent 0:05ccbd4f84f1 831 f->seen_ack = 0;
hendrikvincent 0:05ccbd4f84f1 832
hendrikvincent 0:05ccbd4f84f1 833 /*
hendrikvincent 0:05ccbd4f84f1 834 * Make up the request packet
hendrikvincent 0:05ccbd4f84f1 835 */
hendrikvincent 0:05ccbd4f84f1 836 outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN;
hendrikvincent 0:05ccbd4f84f1 837 if( f->callbacks->cilen && f->callbacks->addci ) {
hendrikvincent 0:05ccbd4f84f1 838 cilen = (*f->callbacks->cilen)(f);
hendrikvincent 0:05ccbd4f84f1 839 if( cilen > peer_mru[f->unit] - (int)HEADERLEN ) {
hendrikvincent 0:05ccbd4f84f1 840 cilen = peer_mru[f->unit] - HEADERLEN;
hendrikvincent 0:05ccbd4f84f1 841 }
hendrikvincent 0:05ccbd4f84f1 842 if (f->callbacks->addci) {
hendrikvincent 0:05ccbd4f84f1 843 (*f->callbacks->addci)(f, outp, &cilen);
hendrikvincent 0:05ccbd4f84f1 844 }
hendrikvincent 0:05ccbd4f84f1 845 } else {
hendrikvincent 0:05ccbd4f84f1 846 cilen = 0;
hendrikvincent 0:05ccbd4f84f1 847 }
hendrikvincent 0:05ccbd4f84f1 848
hendrikvincent 0:05ccbd4f84f1 849 /* send the request to our peer */
hendrikvincent 0:05ccbd4f84f1 850 fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
hendrikvincent 0:05ccbd4f84f1 851
hendrikvincent 0:05ccbd4f84f1 852 /* start the retransmit timer */
hendrikvincent 0:05ccbd4f84f1 853 --f->retransmits;
hendrikvincent 0:05ccbd4f84f1 854 TIMEOUT(fsm_timeout, f, f->timeouttime);
hendrikvincent 0:05ccbd4f84f1 855
hendrikvincent 0:05ccbd4f84f1 856 FSMDEBUG(LOG_INFO, ("%s: sending Configure-Request, id %d\n",
hendrikvincent 0:05ccbd4f84f1 857 PROTO_NAME(f), f->reqid));
hendrikvincent 0:05ccbd4f84f1 858 }
hendrikvincent 0:05ccbd4f84f1 859
hendrikvincent 0:05ccbd4f84f1 860
hendrikvincent 0:05ccbd4f84f1 861 /*
hendrikvincent 0:05ccbd4f84f1 862 * fsm_sdata - Send some data.
hendrikvincent 0:05ccbd4f84f1 863 *
hendrikvincent 0:05ccbd4f84f1 864 * Used for all packets sent to our peer by this module.
hendrikvincent 0:05ccbd4f84f1 865 */
hendrikvincent 0:05ccbd4f84f1 866 void
hendrikvincent 0:05ccbd4f84f1 867 fsm_sdata( fsm *f, u_char code, u_char id, u_char *data, int datalen)
hendrikvincent 0:05ccbd4f84f1 868 {
hendrikvincent 0:05ccbd4f84f1 869 u_char *outp;
hendrikvincent 0:05ccbd4f84f1 870 int outlen;
hendrikvincent 0:05ccbd4f84f1 871
hendrikvincent 0:05ccbd4f84f1 872 /* Adjust length to be smaller than MTU */
hendrikvincent 0:05ccbd4f84f1 873 outp = outpacket_buf[f->unit];
hendrikvincent 0:05ccbd4f84f1 874 if (datalen > peer_mru[f->unit] - (int)HEADERLEN) {
hendrikvincent 0:05ccbd4f84f1 875 datalen = peer_mru[f->unit] - HEADERLEN;
hendrikvincent 0:05ccbd4f84f1 876 }
hendrikvincent 0:05ccbd4f84f1 877 if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) {
hendrikvincent 0:05ccbd4f84f1 878 BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
hendrikvincent 0:05ccbd4f84f1 879 }
hendrikvincent 0:05ccbd4f84f1 880 outlen = datalen + HEADERLEN;
hendrikvincent 0:05ccbd4f84f1 881 MAKEHEADER(outp, f->protocol);
hendrikvincent 0:05ccbd4f84f1 882 PUTCHAR(code, outp);
hendrikvincent 0:05ccbd4f84f1 883 PUTCHAR(id, outp);
hendrikvincent 0:05ccbd4f84f1 884 PUTSHORT(outlen, outp);
hendrikvincent 0:05ccbd4f84f1 885 pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);
hendrikvincent 0:05ccbd4f84f1 886 FSMDEBUG(LOG_INFO, ("fsm_sdata(%s): Sent code %d,%d,%d.\n",
hendrikvincent 0:05ccbd4f84f1 887 PROTO_NAME(f), code, id, outlen));
hendrikvincent 0:05ccbd4f84f1 888 }
hendrikvincent 0:05ccbd4f84f1 889
hendrikvincent 0:05ccbd4f84f1 890 #endif /* PPP_SUPPORT */