[En-Nut-Discussion] Help needed with Ethernut and PPP connection
pbisiac at inwind.it
pbisiac at inwind.it
Mon Apr 10 10:53:39 CEST 2006
Hello, I am asking for help from the forum because I couldn't manage to setup a PPP connection with any italian provider (Telecom Italia, Wind, Tiscali).
I am using ethernut 1.3G, OS 4.1.1, GCC for AVR. I connected the second serial (on the expansion bus) to a US robotics 56K modem via a level converter (MAX232), while the first serial is used for debugging. I am using the example "ppp.c" slightly modified, wich I enclose for completeness:
---------------------------------------------------------------------
/*
* Copyright (C) 2003 by egnite Software GmbH. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
* SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* For additional information see http://www.ethernut.de/
*
*/
/*!
* $Log: pppc.c,v $
* Revision 1.6 2005/10/16 23:22:44 hwmaier
* Commented out unreferenced include statement hd44780.h
*
* Revision 1.5 2005/04/30 16:42:41 chaac
* Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG
* is defined in NutConf, it will make effect where it is used.
*
* Revision 1.4 2005/02/23 04:44:35 hwmaier
* Changes in order to support AT90CAN128
*
* Revision 1.3 2004/01/28 14:24:47 drsung
* Bugfix for ICCAVR
*
* Revision 1.2 2003/11/06 09:24:50 haraldkipp
* Added a note that debug output will hang ATmega103
*
* Revision 1.1 2003/08/14 14:57:07 haraldkipp
* First release
*
*/
/*!
* \example pppc/pppc.c
*
* PPP client. Similar to the TCP server sample, but uses PPP over RS232.
*
* The default settings in this sample may be used to connect to a RAS
* server of a Windows PC. When adding a similar modem script, it will
* also work with a Linux PC nearly out of the box. At least you need
* to change the PPPUSER and PPPPASS.
*
* \bug This sample works with ICCAVR (6.28 tested) only with debugging
* enabled.
*
* \bug Not working with ATmega103. Debug output needs to be removed.
*/
//#define NUTDEBUG
/*
* PPP user and password.
*/
#define PPPUSER "pbisiac" // Libero, non va
#define PPPPASS "******" // Libero, non va
/*
* The Nut/OS modem chat utility works similar to the the UNIX
* chat script. This one is used to connect to a Windows PC
* using a direct cable.
*/
//#define PPPCHAT "TIMEOUT 2 '' CLIENT\\c CLIENTSERVER"
/*
* A very simple modem script.
*/
//#define PPPCHAT "TIMEOUT 25 '' AT OK ATX3DT0492960000 CONNECT"
#define PPPCHAT "TIMEOUT 45 '' AT OK ATX3E0DT0,0418290000 CONNECT" // Libero, non va (E0 == echo off ?!?)
//#define PPPCHAT "TIMEOUT 45 '' AT OK ATX3DT0,0493000000 CONNECT" // Tiscali, non va
//#define PPPCHAT "TIMEOUT 45 '' AT OK ATX3DT0,7020001033 CONNECT" // Tin.it, non va (numero inesistente ?!?)
/*
* PPP device settings.
*/
#define PPPDEV devAhdlc1 /* Use HDLC driver. */
//#define PPPDEV devUart1 /* Use standard UART driver. */
#define PPPCOM "uart1" /* Physical device name. */
#define PPPSPEED 115200 /* Baudrate. */
#define PPPRXTO 1000 /* Character receive timeout. */
/*
* Server input buffer size.
*/
#define RXBUFFSIZE 256
#include <cfg/os.h>
#include <dev/debug.h>
//#include <dev/hd44780.h>
#include <dev/ahdlcavr.h>
#include <dev/uartavr.h>
#include <dev/ppp.h>
#include <dev/chat.h>
#include <sys/version.h>
#include <sys/heap.h>
#include <sys/thread.h>
#include <sys/socket.h>
#include <sys/timer.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if_var.h>
#include <net/route.h>
#ifdef NUTDEBUG
#include <net/netdebug.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#if defined(__IMAGECRAFT__)
#define CC_STRING "ICCAVR"
#elif defined(__GNUC__)
#define CC_STRING "AVRGCC"
#else
#define CC_STRING "Compiler unknown"
#endif
/*
* Debug output device settings.
*/
#ifdef __AVR_ENHANCED__
//#define DBGDEV devAhdlc0
#define DBGDEV devDebug0 /* Use debug driver. */
//#define DBGDEV devUart0 /* Use standard UART driver. */
#define DBGCOM "uart0" /* Device name. */
#define DBGSPEED 115200 /* Baudrate. */
#endif
prog_char vbanner_P[] = "\n\nPPP Client Sample - Nut/OS %s - " CC_STRING "\n";
prog_char banner_P[] = "200 Welcome to tcps. Type help to get help.\r\n";
prog_char help_P[] = "400 List of commands follows\r\n"
"m[emory]\tQueries number of RAM bytes free.\r\n"
"t[hreads]\tLists all created threads.\r\n"
"ti[mers]\tLists all running timers.\r\n" "q[uit]\t\tTerminates connection.\r\n" ".\r\n";
prog_char thread_intro_P[] = "220 List of threads with name,state,prio,stack,mem,timeout follows\r\n";
prog_char timer_intro_P[] = "221 List of timers with ticks left and interval follows\r\n";
prog_char mem_fmt_P[] = "210 %u bytes RAM free\r\n";
/*
* Process client requests.
*/
void ProcessRequests(FILE * stream)
{
int got;
char *cp;
char *buff;
/*
* We allocate the input buffer from heap memory.
*/
buff = malloc(RXBUFFSIZE);
/*
* Send a welcome banner.
*/
fputs_P(banner_P, stream);
for (;;) {
/*
* Flush output and read a line.
*/
fflush(stream);
if (fgets(buff, RXBUFFSIZE, stream) == 0)
break;
/*
* Chop off EOL.
*/
if ((cp = strchr(buff, '\r')) != 0)
*cp = 0;
if ((cp = strchr(buff, '\n')) != 0)
*cp = 0;
/*
* Ignore blank lines.
*/
got = strlen(buff);
if (got == 0)
continue;
/*
* Memory info.
*/
if (strncmp(buff, "memory", got) == 0) {
fprintf_P(stream, mem_fmt_P, NutHeapAvailable());
continue;
}
/*
* List threads.
*/
if (strncmp(buff, "threads", got) == 0) {
NUTTHREADINFO *tdp;
NUTTIMERINFO *tnp;
fputs_P(thread_intro_P, stream);
for (tdp = nutThreadList; tdp; tdp = tdp->td_next) {
fputs(tdp->td_name, stream);
switch (tdp->td_state) {
case TDS_TERM:
fputs("\tTerm\t", stream);
break;
case TDS_RUNNING:
fputs("\tRun\t", stream);
break;
case TDS_READY:
fputs("\tReady\t", stream);
break;
case TDS_SLEEP:
fputs("\tSleep\t", stream);
break;
}
fprintf(stream, "%u\t%u", tdp->td_priority, (u_short) tdp->td_sp - (u_short) tdp->td_memory);
if (*((u_long *) tdp->td_memory) != DEADBEEF)
fputs("\tCorrupted\t", stream);
else
fputs("\tOK\t", stream);
if ((tnp = (NUTTIMERINFO *) tdp->td_timer) != 0)
fprintf(stream, "%lu\r\n", tnp->tn_ticks_left);
else
fputs("None\r\n", stream);
}
fputs(".\r\n", stream);
continue;
}
/*
* List timers.
*/
if (strncmp("timers", buff, got) == 0) {
NUTTIMERINFO *tnp;
fputs_P(timer_intro_P, stream);
for (tnp = nutTimerList; tnp; tnp = tnp->tn_next) {
fprintf(stream, "%lu\t", tnp->tn_ticks_left);
if (tnp->tn_ticks)
fprintf(stream, "%lu\r\n", tnp->tn_ticks);
else
fputs("Oneshot\r\n", stream);
}
fputs(".\r\n", stream);
continue;
}
/*
* Quit connection.
*/
if (strncmp("quit", buff, got) == 0) {
break;
}
/*
* Display help text on any unknown command.
*/
fputs_P(help_P, stream);
}
}
/*
* PPP client application entry.
*/
int main(void)
{
int pppcom;
PPPDCB *dcb;
u_long lctl;
int rc;
/*
* Register our devices.
*/
#ifdef __AVR_ENHANCED__
NutRegisterDevice(&DBGDEV, 0, 0); // devUart0 ovvero devDebug0
#endif
NutRegisterDevice(&PPPDEV, 0, 0); // devUart1 ovvero devAhdlc1
NutRegisterDevice(&devPpp, 0, 0); // devPpp e' il nome del device implementato da dev\ppp.h
/*
* Open debug device for standard output.
*/
if(freopen("uart0", "w", stdout) == 0) {
for(;;);
}
/*
* Set debug output speed.
*/
#ifdef __AVR_ENHANCED__
lctl = DBGSPEED;
_ioctl(_fileno(stdout), UART_SETSPEED, &lctl);
#endif
/*
* Display banner including compiler info and Nut/OS version.
*/
printf_P(vbanner_P, NutVersionString());
/*
* Open PPP device. Specify physical device, user and password.
*/
printf("Open uart...");
if ((pppcom = _open("ppp:" PPPCOM "/" PPPUSER "/" PPPPASS, _O_RDWR | _O_BINARY)) == -1) {
printf("Failed to open " PPPCOM "\n");
for (;;);
}
puts("done");
/*
* Set PPP line speed.
*/
lctl = PPPSPEED;
_ioctl(pppcom, UART_SETSPEED, &lctl);
/*
* The PPP driver doesn't set any receive timeout, but
* may require it.
*/
lctl = PPPRXTO;
_ioctl(pppcom, UART_SETREADTIMEOUT, &lctl);
#ifdef NUTDEBUG
/*
* Optionally enable PPP trace. Per debuggare occore la debug
* version delle Nut/OS libraries (opzione RTOS Kernel - OS Debug)
*/
NutTracePPP(stdout, 1); // 1: tracing enabled
// NutTraceTcp(stdout, 1); // Vedi "http://www.faqs.org/rfcs/rfc1548.html" per il PPP (anche 1547)
// NutTraceOs(stdout, 0);
// NutTraceHeap(stdout, 0);
// NutTracePPP(stdout, 0);
#endif
/*
* This delay may be removed. It is quite helpful during development.
*/
NutSleep(5000);
/*
* PPP connection loop.
*/
for (;;) {
/*
* Connect using a chat script. We may also set any
* required hardware handshake line at this stage.
*/
printf("Connecting...");
if ((rc = NutChat(pppcom, PPPCHAT)) != 0) {
printf("no connect, reason = %d\n", rc);
continue;
}
puts("done");
/*
* We are connected, configure our PPP network interface.
* This will initiate the PPP configuration negotiation
* and authentication with the server.
*/
printf("Configure PPP...");
rc = NutNetIfConfig("ppp", 0, 0, 0);
if (rc != 0) {
puts("failed");
/*
* Optionally toggle DTR to hang up the modem.
*/
continue;
}
puts("done");
/*
* Set name server and default route. Actually the PPP interface
* should do this, but the current release doesn't.
*/
dcb = devPpp.dev_dcb;
NutDnsConfig2(0, 0, dcb->dcb_ip_dns1, dcb->dcb_ip_dns2);
NutIpRouteAdd(0, 0, dcb->dcb_remote_ip, &devPpp);
/*
* Display our IP settings.
*/
printf(" Local IP: %s\n", inet_ntoa(dcb->dcb_local_ip));
printf(" Remote IP: %s\n", inet_ntoa(dcb->dcb_remote_ip));
printf(" Primary DNS: %s\n", inet_ntoa(dcb->dcb_ip_dns1));
printf("Secondary DNS: %s\n", inet_ntoa(dcb->dcb_ip_dns2));
/*
* Client connection loop.
*/
for (;;) {
TCPSOCKET *sock;
FILE *stream;
/*
* Create a socket.
*/
if ((sock = NutTcpCreateSocket()) != 0) {
/*
* Listen on port 23. If we return, we got a client.
*/
printf("Waiting for a client...");
if (NutTcpAccept(sock, 23) == 0) {
puts("connected");
/*
* Open a stream and associate it with the socket, so
* we can use standard I/O. Note, that socket streams
* currently do support text mode.
*/
if ((stream = _fdopen((int) sock, "r+b")) != 0) {
/*
* Process client requests.
*/
ProcessRequests(stream);
puts("\nDisconnected");
/*
* Close the stream.
*/
fclose(stream);
} else {
puts("Assigning a stream failed");
}
} else {
puts("failed");
}
/* * Close our socket. */ NutTcpCloseSocket(sock); }
NutSleep(1000); printf("%u bytes free\n", NutHeapAvailable()); }
}
}
---------------------------------------------------------------------
After the "CONNECT" answer from modem, Ethernut tries to send the same string to ISP for 4 times, with a 5-6 seconds delay between each one, and then fails.
I made a little circuit to capture the dataflow in both directions, Ethernut->modem and modem->Ethernut.
This is the data sent from modem->Ethernut:
OK
ATX3E0DT0,0418290000
CONNECT 49333/ARQ/V92/LAPM/V42BIS
<around 20 seconds...>
NO CARRIER
This is the data sent from Ethernut->modem in hex format:
7E FF 7D 23 C0 21 7D 21 7D 21 7D 20 7D 30 7D 22 7D 26 7D 20 7D 2A 7D 20 7D 20 7D 25 7D 26 7D 5E 56 34 7D 32 7D 28 30 7E 41 54 0D
This is the output from debug serial (function NutDumpPpp in pppdebug.c):
PPP Client Sample - Nut/OS 4.1.1.0 - AVRGCC
Open uart...done
Connecting...done
Configure PPP...
[LCP-LOWERUP]
PPP<(20){FF 03 C0 21 EF BE AD DE DC 61 00 00 61 00 00 BE AD DE 2C 00 }[LCP-001(1
6)][CONFREQ][OPT(12)][ACCM=0x000A0000][MAGIC=0x7E563412]
please notice the string in curly brackets: I modified pppdebug.c in source directory, to directly log the output buffer (NETBUF):
int i;
u_char *p = nb->nb_dl.vp;
fprintf(stream, "{");
for (i = 0; i < nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz; i++)
fputc(*p++, stream);
fprintf(stream, "%02X ", *p++);
fprintf(stream, "}");
My diagnose is that Ethernut tries to reach ISP for n times, and then fails, getting no answer. I red RFC1662 (PPP in HDLC-like Framing) and it seems like the output buffer is not correcly trans-coded in HDLC Format, with regard to
escape sequence mapping. So the ISP doesn't understand the packet at all and doesn't answer.
Does anybody had similar problems ?
Thanks in advance,
Paolo
More information about the En-Nut-Discussion
mailing list