cbcp
switch (cbcp->fsm.state) {
cbcp->p->dl->name);
cbcp->p->dl->name, missed);
datalink_CBCPFailed(cbcp->p->dl);
cbcp_StartTimer(struct cbcp *cbcp, int timeout)
timer_Stop(&cbcp->fsm.timer);
cbcp->fsm.timer.func = cbcp_Timeout;
cbcp->fsm.timer.name = "cbcp";
cbcp->fsm.timer.load = timeout * SECTICKS;
cbcp->fsm.timer.arg = cbcp;
timer_Start(&cbcp->fsm.timer);
cbcp_NewPhase(struct cbcp *cbcp, int new)
if (cbcp->fsm.state != new) {
log_Printf(LogCBCP, "%s: State change %s --> %s\n", cbcp->p->dl->name,
cbcpstate(cbcp->fsm.state), cbcpstate(new));
cbcp->fsm.state = new;
cbcp_Output(struct cbcp *cbcp, u_char code, struct cbcp_data *data)
head->id = cbcp->fsm.id;
link_PushPacket(&cbcp->p->link, bp, cbcp->p->dl->bundle,
LINK_QUEUES(&cbcp->p->link) - 1, PROTO_CBCP);
cbcp_SendReq(struct cbcp *cbcp)
char list[sizeof cbcp->fsm.phone], *next;
log_Printf(LogCBCP, "%s: SendReq(%d) state = %s\n", cbcp->p->dl->name,
cbcp->fsm.id, cbcpstate(cbcp->fsm.state));
data.type = cbcp->fsm.type;
strncpy(list, cbcp->fsm.phone, sizeof list - 1);
cbcp_Output(cbcp, CBCP_REQ, &data);
cbcp->fsm.restart--;
cbcp_StartTimer(cbcp, cbcp->fsm.delay);
cbcp_NewPhase(cbcp, CBCP_REQSENT); /* Wait for a RESPONSE */
cbcp_Up(struct cbcp *cbcp)
struct lcp *lcp = &cbcp->p->link.lcp;
cbcp->fsm.delay = cbcp->p->dl->cfg.cbcp.delay;
if (*cbcp->p->dl->peer.authname == '\0' ||
!auth_SetPhoneList(cbcp->p->dl->peer.authname, cbcp->fsm.phone,
sizeof cbcp->fsm.phone)) {
strncpy(cbcp->fsm.phone, cbcp->p->dl->cfg.cbcp.phone,
sizeof cbcp->fsm.phone - 1);
cbcp->fsm.phone[sizeof cbcp->fsm.phone - 1] = '\0';
if (*cbcp->fsm.phone == '\0')
cbcp->fsm.type = CBCP_NONUM;
else if (!strcmp(cbcp->fsm.phone, "*")) {
cbcp->fsm.type = CBCP_SERVERNUM;
*cbcp->fsm.phone = '\0';
cbcp->fsm.type = CBCP_CLIENTNUM;
cbcp_NewPhase(cbcp, CBCP_STOPPED); /* Wait for a REQ */
cbcp_StartTimer(cbcp, cbcp->fsm.delay * DEF_FSMTRIES);
if (*cbcp->fsm.phone == '\0')
cbcp->fsm.type = CBCP_NONUM;
else if (!strcmp(cbcp->fsm.phone, "*")) {
cbcp->fsm.type = CBCP_CLIENTNUM;
*cbcp->fsm.phone = '\0';
} else if (strchr(cbcp->fsm.phone, ','))
cbcp->fsm.type = CBCP_LISTNUM;
cbcp->fsm.type = CBCP_SERVERNUM;
cbcp->fsm.restart = DEF_FSMTRIES;
cbcp_SendReq(cbcp);
cbcp_AdjustResponse(struct cbcp *cbcp, struct cbcp_data *data)
if (cbcp->p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))
cbcp->fsm.type = CBCP_NONUM;
if (cbcp->fsm.type == CBCP_CLIENTNUM) {
ptr = strchr(cbcp->fsm.phone, ',');
if (cbcp->fsm.type == CBCP_SERVERNUM) {
*cbcp->fsm.phone = '\0';
} else if (cbcp->fsm.type == CBCP_CLIENTNUM) {
char list[sizeof cbcp->fsm.phone], *next;
strncpy(list, cbcp->fsm.phone, sizeof list - 1);
cbcp->fsm.type = CBCP_SERVERNUM;
strcpy(cbcp->fsm.phone, next);
if (cbcp->fsm.type == CBCP_CLIENTNUM || cbcp->fsm.type == CBCP_LISTNUM) {
char list[sizeof cbcp->fsm.phone], *next, *end;
strncpy(list, cbcp->fsm.phone, sizeof list - 1);
cbcp->fsm.type = CBCP_LISTNUM;
strcpy(cbcp->fsm.phone, next);
cbcp_SendResponse(struct cbcp *cbcp)
log_Printf(LogCBCP, "%s: SendResponse(%d) state = %s\n", cbcp->p->dl->name,
cbcp->fsm.id, cbcpstate(cbcp->fsm.state));
data.type = cbcp->fsm.type;
data.delay = cbcp->fsm.delay;
else if (*cbcp->fsm.phone) {
strncpy(addr->addr, cbcp->fsm.phone, sizeof addr->addr - 1);
cbcp_Output(cbcp, CBCP_RESPONSE, &data);
cbcp->fsm.restart--;
cbcp_StartTimer(cbcp, cbcp->fsm.delay);
cbcp_NewPhase(cbcp, CBCP_RESPSENT); /* Wait for an ACK */
cbcp_CheckResponse(struct cbcp *cbcp, struct cbcp_data *data)
if (data->type == cbcp->fsm.type) {
switch (cbcp->fsm.type) {
strncpy(cbcp->fsm.phone, addr->addr, sizeof cbcp->fsm.phone - 1);
cbcp->fsm.phone[sizeof cbcp->fsm.phone - 1] = '\0';
cbcp->fsm.delay = data->delay;
cbcp->fsm.delay = data->delay;
char list[sizeof cbcp->fsm.phone], *next;
strncpy(list, cbcp->fsm.phone, sizeof list - 1);
strcpy(cbcp->fsm.phone, next);
cbcp->fsm.delay = data->delay;
(int)cbcp->fsm.type);
} else if (data->type == CBCP_NONUM && cbcp->fsm.type == CBCP_CLIENTNUM) {
cbcp->fsm.type = CBCP_NONUM;
cbcp_SendAck(struct cbcp *cbcp)
log_Printf(LogCBCP, "%s: SendAck(%d) state = %s\n", cbcp->p->dl->name,
cbcp->fsm.id, cbcpstate(cbcp->fsm.state));
data.type = cbcp->fsm.type;
strncpy(addr->addr, cbcp->fsm.phone, sizeof addr->addr - 1);
data.delay = cbcp->fsm.delay;
data.delay = cbcp->fsm.delay;
cbcp_Output(cbcp, CBCP_ACK, &data);
cbcp->fsm.restart--;
cbcp_StartTimer(cbcp, cbcp->fsm.delay);
cbcp_NewPhase(cbcp, CBCP_ACKSENT); /* Wait for an ACK */
struct cbcp *cbcp = &p->dl->cbcp;
cbcp_Init(struct cbcp *cbcp, struct physical *p)
cbcp->required = 0;
cbcp->fsm.state = CBCP_CLOSED;
p->dl->name, head->id, cbcpstate(cbcp->fsm.state));
if (cbcp->fsm.state == CBCP_STOPPED || cbcp->fsm.state == CBCP_RESPSENT) {
timer_Stop(&cbcp->fsm.timer);
if (cbcp_AdjustResponse(cbcp, data)) {
cbcp->fsm.restart = DEF_FSMTRIES;
cbcp->fsm.id = head->id;
cbcp_SendResponse(cbcp);
datalink_CBCPFailed(cbcp->p->dl);
cbcp->fsm.id = 0;
p->dl->name, head->id, cbcpstate(cbcp->fsm.state));
if (cbcp->fsm.id != head->id) {
cbcp->fsm.delay = 0;
cbcp->fsm.id, head->id);
cbcp->fsm.id = head->id;
if (cbcp->fsm.state == CBCP_REQSENT || cbcp->fsm.state == CBCP_ACKSENT) {
timer_Stop(&cbcp->fsm.timer);
switch (cbcp_CheckResponse(cbcp, data)) {
cbcp_SendReq(cbcp);
*cbcp->fsm.phone = '\0';
cbcp->fsm.restart = DEF_FSMTRIES;
cbcp_SendAck(cbcp);
if (cbcp->fsm.type == CBCP_NONUM) {
timer_Stop(&cbcp->fsm.timer);
datalink_NCPUp(cbcp->p->dl);
memset(&cbcp->fsm.timer, '\0', sizeof cbcp->fsm.timer);
datalink_CBCPFailed(cbcp->p->dl);
cbcp->p = p;
p->dl->name, head->id, cbcpstate(cbcp->fsm.state));
if (cbcp->fsm.id != head->id) {
cbcp->fsm.id, head->id);
cbcp->fsm.id = head->id;
if (cbcp->fsm.type == CBCP_NONUM) {
timer_Stop(&cbcp->fsm.timer);
datalink_NCPUp(cbcp->p->dl);
} else if (cbcp->fsm.state == CBCP_RESPSENT) {
timer_Stop(&cbcp->fsm.timer);
datalink_CBCPComplete(cbcp->p->dl);
static void cbcp_SendReq(struct cbcp *);
cbcp_Down(struct cbcp *cbcp)
timer_Stop(&cbcp->fsm.timer);
cbcp_NewPhase(cbcp, CBCP_CLOSED);
static void cbcp_SendResponse(struct cbcp *);
cbcp->required = 0;
if (p->dl->cbcp.fsm.state == CBCP_ACKSENT) {
p->dl->cbcp.required = 1;
static void cbcp_SendAck(struct cbcp *);
p->dl->cbcp.fsm.phone);
cbcp_NewPhase(&p->dl->cbcp, CBCP_CLOSED);
struct cbcp *cbcp = (struct cbcp *)v;
timer_Stop(&cbcp->fsm.timer);
if (cbcp->fsm.restart) {
switch (cbcp->fsm.state) {
cbcp->p->dl->name);
cbcp_SendReq(cbcp);
cbcp_SendResponse(cbcp);
cbcp_SendAck(cbcp);
extern void cbcp_Init(struct cbcp *, struct physical *);
extern void cbcp_Up(struct cbcp *);
extern void cbcp_Down(struct cbcp *);
cx->cfg.cbcp.delay = 0;
*cx->cfg.cbcp.phone = '\0';
cx->cfg.cbcp.fsmretry = DEF_FSMRETRY;
strncpy(cx->cfg.cbcp.phone, arg->argv[arg->argn],
sizeof cx->cfg.cbcp.phone - 1);
cx->cfg.cbcp.phone[sizeof cx->cfg.cbcp.phone - 1] = '\0';
cx->cfg.cbcp.delay = atoi(arg->argv[arg->argn + 1]);
cx->cfg.cbcp.fsmretry = long_val;
arg->cx->cfg.cbcp.delay);
if (!strcmp(arg->cx->cfg.cbcp.phone, "*")) {
prompt_Printf(arg->prompt, "%s\n", arg->cx->cfg.cbcp.phone);
arg->cx->cfg.cbcp.fsmretry);
if (dl->cbcp.required) {
log_Printf(LogPHASE, "Call peer back on %s\n", dl->cbcp.fsm.phone);
strncpy(dl->cfg.phone.list, dl->cbcp.fsm.phone,
cbcp_Init(&dl->cbcp, dl->physical);
cbcp_Down(&dl->cbcp);
if (dl->cbcp.fsm.delay < dl->cfg.dial.timeout)
dl->cbcp.fsm.delay = dl->cfg.dial.timeout;
datalink_StartDialTimer(dl, dl->cbcp.fsm.delay);
cbcp_Down(&dl->cbcp);
cbcp_Down(&dl->cbcp);
cbcp_Up(&dl->cbcp);
auth_SetPhoneList(dl->peer.authname, dl->cbcp.fsm.phone,
sizeof dl->cbcp.fsm.phone);
if (*dl->cbcp.fsm.phone == '\0' || !strcmp(dl->cbcp.fsm.phone, "*")) {
*dl->cbcp.fsm.phone = '\0';
char *ptr = strchr(dl->cbcp.fsm.phone, ',');
dl->cbcp.fsm.phone);
dl->cbcp.required = 1;
dl->cbcp.fsm.delay = 0;
strncpy(dl->cbcp.fsm.phone, dl->physical->link.lcp.his_callback.msg,
sizeof dl->cbcp.fsm.phone - 1);
dl->cbcp.fsm.phone[sizeof dl->cbcp.fsm.phone - 1] = '\0';
dl->cbcp.fsm.phone);
dl->cbcp.required = 1;
dl->cbcp.fsm.delay = 0;
if (!dl->cbcp.required)
cbcp_Down(&dl->cbcp);
dl->cfg.cbcp.delay = 0;
*dl->cfg.cbcp.phone = '\0';
dl->cfg.cbcp.fsmretry = DEF_FSMRETRY;
cbcp_Init(&dl->cbcp, dl->physical);
cbcp_Init(&dl->cbcp, dl->physical);
struct cbcpcfg cbcp; /* Direction depends on phys type & callback */
struct cbcp cbcp;