blob: a3cd9d5fc7e34c453e7433d928da3adf002ceb8d [file] [log] [blame]
/*
* Copyright (c) 2019-2020 Grinn
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_l2_ppp, CONFIG_NET_L2_PPP_LOG_LEVEL);
#include <zephyr/net/net_pkt.h>
#include "ppp_internal.h"
static enum net_verdict pap_handle(struct ppp_context *ctx,
struct net_if *iface,
struct net_pkt *pkt)
{
return ppp_fsm_input(&ctx->pap.fsm, PPP_PAP, pkt);
}
static struct net_pkt *pap_config_info_add(struct ppp_fsm *fsm)
{
uint8_t payload[] = { 5, 'b', 'l', 'a', 'n', 'k',
5, 'b', 'l', 'a', 'n', 'k' };
struct net_pkt *pkt;
pkt = net_pkt_alloc_with_buffer(ppp_fsm_iface(fsm), sizeof(payload),
AF_UNSPEC, 0, PPP_BUF_ALLOC_TIMEOUT);
if (!pkt) {
return NULL;
}
(void)net_pkt_write(pkt, payload, sizeof(payload));
return pkt;
}
static int pap_config_info_ack(struct ppp_fsm *fsm,
struct net_pkt *pkt,
uint16_t length)
{
/*
* We only support one way negotiation for now, so move to ACK_SENT
* phase right away.
*/
if (fsm->state == PPP_REQUEST_SENT) {
ppp_change_state(fsm, PPP_ACK_SENT);
}
return 0;
}
static void pap_lower_down(struct ppp_context *ctx)
{
ppp_fsm_lower_down(&ctx->pap.fsm);
}
static void pap_lower_up(struct ppp_context *ctx)
{
ppp_fsm_lower_up(&ctx->pap.fsm);
}
static void pap_open(struct ppp_context *ctx)
{
ppp_fsm_open(&ctx->pap.fsm);
}
static void pap_close(struct ppp_context *ctx, const uint8_t *reason)
{
ppp_fsm_close(&ctx->pap.fsm, reason);
}
static void pap_up(struct ppp_fsm *fsm)
{
struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
pap.fsm);
if (ctx->is_pap_up) {
return;
}
ctx->is_pap_up = true;
NET_DBG("[%s/%p] Current state %s (%d)", fsm->name, fsm,
ppp_state_str(fsm->state), fsm->state);
ppp_link_authenticated(ctx);
}
static void pap_down(struct ppp_fsm *fsm)
{
struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
pap.fsm);
if (!ctx->is_pap_up) {
return;
}
ctx->is_pap_up = false;
}
static void pap_finished(struct ppp_fsm *fsm)
{
struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
pap.fsm);
if (!ctx->is_pap_open) {
return;
}
ctx->is_pap_open = false;
}
static void pap_proto_reject(struct ppp_fsm *fsm)
{
ppp_fsm_lower_down(fsm);
}
static void pap_init(struct ppp_context *ctx)
{
NET_DBG("proto %s (0x%04x) fsm %p", ppp_proto2str(PPP_PAP), PPP_PAP,
&ctx->pap.fsm);
memset(&ctx->pap.fsm, 0, sizeof(ctx->pap.fsm));
ppp_fsm_init(&ctx->pap.fsm, PPP_PAP);
ppp_fsm_name_set(&ctx->pap.fsm, ppp_proto2str(PPP_PAP));
ctx->pap.fsm.cb.up = pap_up;
ctx->pap.fsm.cb.down = pap_down;
ctx->pap.fsm.cb.finished = pap_finished;
ctx->pap.fsm.cb.proto_reject = pap_proto_reject;
ctx->pap.fsm.cb.config_info_add = pap_config_info_add;
ctx->pap.fsm.cb.config_info_ack = pap_config_info_ack;
}
PPP_PROTOCOL_REGISTER(PAP, PPP_PAP,
pap_init, pap_handle,
pap_lower_up, pap_lower_down,
pap_open, pap_close);