backport
[AROS.git] / workbench / devs / networks / ppp / ModemManager / misc.c
blobe3a11038f1028078ab608cacbf14e8da4cda825a
1 /*
2 * $Id$
3 */
5 #define DEBUG 1
7 #include <exec/types.h>
8 #include <exec/resident.h>
9 #include <exec/io.h>
10 #include <exec/ports.h>
11 #include <exec/errors.h>
12 #include <exec/lists.h>
14 #ifdef __AROS__
15 #include <aros/io.h>
16 #include <aros/libcall.h>
17 #include <aros/symbolsets.h>
18 #endif
20 #include <devices/sana2.h>
21 #include <devices/sana2specialstats.h>
22 #include <devices/newstyle.h>
23 #include <devices/timer.h>
24 #include <devices/serial.h>
25 #include <devices/timer.h>
27 #include <utility/utility.h>
28 #include <utility/tagitem.h>
29 #include <utility/hooks.h>
31 #include <proto/exec.h>
32 #include <proto/dos.h>
33 #ifdef __AROS__
34 #include <proto/oop.h>
35 #else
36 #include <dos/dostags.h>
37 #define SYS_Error SYS_Output
38 #endif
39 #include <proto/timer.h>
40 #include <proto/utility.h>
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <aros/debug.h>
46 #ifdef __AROS__
47 #include <oop/oop.h>
48 #include <hidd/pci.h>
49 #endif
51 #include <ctype.h>
52 #include <ctype.h>
53 #include <devices/serial.h>
54 #include <devices/timer.h>
56 #include "ppp.h"
57 #include "misc.h"
59 #define STRSIZE 1000
61 #define PREFSFILE "ENV:MobileBroadband.prefs"
62 #ifdef __MORPHOS__
63 #define INTERFACEFILE "ENV:sys/net/interfaces"
64 #else
65 #define INTERFACEFILE "ENV:AROSTCP/db/interfaces"
66 #endif
68 BOOL StartStack()
70 ULONG trycount = 0;
71 TEXT arostcppath[256];
73 struct TagItem tags[] =
75 { SYS_Input, (IPTR)NULL },
76 { SYS_Output, (IPTR)NULL },
77 { SYS_Error, (IPTR)NULL },
78 { SYS_Asynch, (IPTR)TRUE },
79 { TAG_DONE, 0 }
82 arostcppath[0] = 0;
83 GetVar( "SYS/Packages/AROSTCP" , arostcppath , 256 , LV_VAR);
84 AddPart(arostcppath, "C", 256);
85 AddPart(arostcppath, "AROSTCP", 256);
87 bug("Start AROSTCP: %s\n",arostcppath);
88 SystemTagList(arostcppath, tags);
90 /* Check if startup successful */
91 trycount = 0;
92 while (!FindTask("bsdsocket.library"))
94 if (trycount > 9) return FALSE;
95 Delay(50);
96 trycount++;
98 return TRUE;
102 BOOL ReadConfig(struct Conf *c){
103 TEXT linebuff[1024],*tok;
104 BPTR ConfigFile;
105 struct at_command *atc;
106 BOOL result = TRUE;
108 strcpy( c->modemmodel , "Unknow");
109 strcpy( c->username , "DummyName");
110 strcpy( c->password , "DummyName");
111 strcpy( c->DeviceName , "usbmodem.device");
112 c->InterfaceName[0] = 0;
114 c->SerUnitNum = -1; // default: test all units
115 c->CommandTimeOut = 10; // default timeout 10 sec.
117 while( atc = (struct at_command *)RemHead( &c->atcl ) ){
118 FreeMem( atc , sizeof(struct at_command) );
121 bug("Read config file:%s\n",PREFSFILE);
122 if(ConfigFile = Open( PREFSFILE ,MODE_OLDFILE)){
123 while(FGets(ConfigFile, linebuff, STRSIZE )){
124 if( ( linebuff[0] == '#' ) | ( linebuff[0] == ';' ) ) /* Skip comment lines */
125 continue;
127 // bug("line:%s:\n",linebuff);
129 if( tok = strtok( &linebuff[0]," \t\n") ){
131 if( strcasecmp("DEVICE",tok) == 0 ){
132 if( tok = strtok( NULL , " \n" ) ) strcpy( c->DeviceName , tok );
133 }else if( strcasecmp("UNIT",tok) == 0 ){
134 if( tok = strtok( NULL , " \n" ) ) c->SerUnitNum = atoi( tok );
135 }else if( strcasecmp("TIMEOUT",tok) == 0 ){
136 if( tok = strtok( NULL , " \n" ) ) c->CommandTimeOut = atoi( tok );
137 }else if( strcasecmp("USERNAME",tok) == 0 ){
138 if( tok = strtok( NULL , " \n" ) ) strcpy( c->username , tok );
139 }else if( strcasecmp("PASSWORD",tok) == 0 ){
140 if( tok = strtok( NULL , " \n" ) ) strcpy( c->password , tok );
143 else if( strcasecmp("SEND",tok) == 0 ){
144 if( tok = strtok( NULL , "\n" ) ){
145 if(atc = AllocMem(sizeof(struct at_command), MEMF_CLEAR | MEMF_PUBLIC )){
146 strcpy( atc->str , tok );
147 AddTail( &c->atcl , (struct Node*)atc );
153 Close(ConfigFile);
154 }else{
155 bug("ModemManager:Config file missing !!!!\n");
156 result = FALSE;
159 bug("Read config file:%s\n",INTERFACEFILE);
160 if(ConfigFile = Open( INTERFACEFILE ,MODE_OLDFILE)){
161 while(FGets(ConfigFile, linebuff, STRSIZE )){
162 if( ( linebuff[0] == '#' ) | ( linebuff[0] == ';' ) ) /* Skip comment lines */
163 continue;
164 if( strcasestr( linebuff , "ppp.device" ) != NULL ){
165 if( tok = strtok( linebuff , " " ) ){ strcpy( c->InterfaceName , tok );
166 break;
170 Close(ConfigFile);
171 }else{
172 bug("ModemManager:Config file missing !!!!\n");
173 result = FALSE;
176 if( c->InterfaceName[0] == 0 ){
177 bug("ModemManager:No PPP interface defined !!!!\n");
178 result = FALSE;
181 bug("Config:\n");
182 bug(" Interface %s\n",c->InterfaceName);
183 bug(" Device %s\n",c->DeviceName);
184 bug(" Unit %d\n",c->SerUnitNum);
185 bug(" username %s\n",c->username);
186 bug(" password %s\n",c->password);
187 bug(" TimeOut %d\n",c->CommandTimeOut);
188 ULONG i=0;
189 ForeachNode(&c->atcl,atc){
190 bug(" Init%d \"%s\"\n",++i,atc->str);
193 return result;
197 BOOL TestModem(struct EasySerial *s,struct Conf *c){
199 UBYTE *buf,*tok;
200 BOOL result=FALSE;
201 bug("ModemTest\n");
202 UBYTE delim[] = ": ,\n\r";
204 if( buf = AllocMem(STRSIZE,MEMF_CLEAR|MEMF_PUBLIC)){
206 result=TRUE;
207 c->signal=-1;
208 c->AccessType=-1;
209 strcpy( c->modemmodel , "Unknow" );
213 DoStr( s , "\r\r\r" );
215 // atz
216 DrainSerial(s);
217 DoStr( s, "ATZ\r" );
218 if( ! GetResponse(s,buf,STRSIZE,5)){
219 bug("ATZ FAIL\n");
220 result = FALSE; break;
223 // echo off
224 DrainSerial(s);
225 DoStr( s, "ATE 0\r" );
226 if( ! GetResponse(s,buf,STRSIZE,5)){
227 bug("ATE 0 FAIL\n");
228 result = FALSE; break;
231 // Get modem model
232 DrainSerial(s);
233 DoStr( s, "AT+GMM\r" );
234 if( ! GetResponse(s,buf,STRSIZE,5)){
235 bug("AT+GMM FAIL\n");
237 else if( tok = strtok( buf , "\n\r" ) ){
238 strcpy( c->modemmodel , tok );
241 // ask signal strength
242 DrainSerial(s);
243 DoStr( s, "AT+CSQ\r" );
244 if( ! GetResponse(s,buf,STRSIZE,5)){
245 bug("AT+CSQ FAIL\n");
247 else if( tok = strtok( buf , delim ) ){
248 if( tok = strtok( NULL , delim ) ){
249 if( isdigit( tok[0] ) ) c->signal = atoi( tok );
253 // Network Registration Status
254 DrainSerial(s);
255 DoStr( s, "AT+COPS?\r" );
256 if( ! GetResponse(s,buf,STRSIZE,5)){
257 bug("AT+COPS? FAIL\n");
258 }else{
259 if( tok = strtok( buf , delim ) ){
260 if( tok = strtok( NULL , delim ) ){
261 if( tok = strtok( NULL , delim ) ){
262 if( tok = strtok( NULL , delim ) ){
263 if( tok = strtok( NULL , delim ) ){
264 if( isdigit( tok[0] ) ) c->AccessType = atoi( tok );
265 }}}}}
268 bug("model=%s\n",c->modemmodel);
269 bug("AccessType=%d\n",c->AccessType);
270 bug("signal=%d\n",c->signal);
272 }while(0);
274 FreeMem( buf , STRSIZE );
276 return result;
280 BOOL DialUp(struct EasySerial *s,struct Conf *c){
282 struct at_command *atc=NULL;
283 UBYTE buf[PPP_MAXARGLEN];
285 // Init commands
286 ForeachNode(&c->atcl,atc){
287 DrainSerial(s);
288 bug("SEND \"%s\"\n",atc->str);
289 DoStr( s, atc->str);
290 DoStr( s, "\r" );
291 if( GetResponse( s , buf , PPP_MAXARGLEN , c->CommandTimeOut )){
292 if( strcasestr(buf,"CONNECT") ) return TRUE;
293 }else{
294 bug("FAIL!\n");
295 break;
299 return FALSE;
305 void SetTimer(struct EasyTimer* t,const ULONG s){
306 if( t ){
307 //bug("setTimer\n");
308 if( t->TimeReq ){
309 AbortIO((struct IORequest *)t->TimeReq);
310 WaitIO((struct IORequest *)t->TimeReq);
311 while(GetMsg(t->TimeMsg));
313 if( s <= 0 ) return;
315 t->TimeReq->tr_time.tv_secs = s;
316 t->TimeReq->tr_time.tv_micro = 0;
317 ((struct IORequest *)t->TimeReq)->io_Command = TR_ADDREQUEST;
318 SendIO( (struct IORequest *)t->TimeReq );
319 //bug("setTimer ok\n");
325 void CloseTimer(struct EasyTimer* t){
326 if( t ){
327 //bug("closeTimer\n");
328 if( t->TimeReq ){
329 AbortIO((struct IORequest *)t->TimeReq);
330 WaitIO((struct IORequest *)t->TimeReq);
331 while(GetMsg(t->TimeMsg));
332 CloseDevice((struct IORequest *)t->TimeReq);
333 DeleteIORequest(t->TimeReq);
335 if(t->TimeMsg) DeleteMsgPort(t->TimeMsg);
336 FreeMem( t , sizeof(struct EasyTimer) );
337 //bug("closeTimer ok\n");
341 struct EasyTimer* OpenTimer(){
342 struct EasyTimer* t;
343 //bug("OpenTimer\n");
344 if( t = AllocMem( sizeof(struct EasyTimer),MEMF_CLEAR|MEMF_PUBLIC) ){
345 if( t->TimeMsg = CreateMsgPort() ){
346 if( t->TimeReq = CreateIORequest((struct MsgPort *)t->TimeMsg, sizeof(struct timerequest))){
347 if(!OpenDevice("timer.device", UNIT_VBLANK,(struct IORequest *)t->TimeReq, 0)){
348 t->TimeReq->tr_time.tv_secs = 0;
349 t->TimeReq->tr_time.tv_micro = 1;
350 ((struct IORequest *)t->TimeReq)->io_Command = TR_ADDREQUEST;
351 DoIO( (struct IORequest *)t->TimeReq );
352 SetTimer(t,0);
353 //bug("OpenTimer ok!\n");
354 return t;
359 //bug("OpenTimer FAIL!\n");
360 CloseTimer(t);
361 return NULL;
364 VOID DoStr(struct EasySerial *s,const STRPTR str){
365 DoBYTES(s,str,strlen((char*) str));
368 void DoBYTES(struct EasySerial *s, BYTE *p,ULONG len){
370 if( ! s ) return;
371 if( ! s->Ok ) return;
373 WaitIO((struct IORequest*)s->SerTx);
375 s->SerTx->IOSer.io_Length = len;
376 s->SerTx->IOSer.io_Data = p;
377 s->SerTx->IOSer.io_Command = CMD_WRITE;
378 DoIO((struct IORequest*)s->SerTx);
381 void SendBYTES(struct EasySerial *s, BYTE *p, ULONG len){
383 if( ! s ) return;
384 if( ! s->Ok ) return;
386 WaitIO((struct IORequest*)s->SerTx);
388 s->SerTx->IOSer.io_Length = len;
389 s->SerTx->IOSer.io_Data = p;
390 s->SerTx->IOSer.io_Command = CMD_WRITE;
391 SendIO((struct IORequest*)s->SerTx);
394 void DrainSerial(struct EasySerial *s){
396 if( ! s ) return;
397 if( ! s->Ok ) return;
399 if( s->SerRx ){
400 Delay(25);
402 AbortIO((struct IORequest *)s->SerRx);
403 WaitIO((struct IORequest *)s->SerRx);
404 while(GetMsg(s->RxPort));
405 s->RxBuff[1]=0;
407 bug("Drain:\n");
408 for(;;){ // Read crap out of serial device.
410 s->SerRx->IOSer.io_Command = SDCMD_QUERY;
411 DoIO((struct IORequest *)s->SerRx);
413 if( s->SerRx->IOSer.io_Error ){
414 bug("DrainSerial(): OOOOPS lost device!\n");
415 s->Ok=FALSE;
416 return;
419 if( s->SerRx->IOSer.io_Actual == 0 ) break;
421 s->SerRx->IOSer.io_Command = CMD_READ;
422 s->SerRx->IOSer.io_Data = s->RxBuff;
423 s->SerRx->IOSer.io_Length = 1;
424 DoIO((struct IORequest *)s->SerRx);
425 if( s->SerRx->IOSer.io_Error ){
426 bug("DrainSerial(): CMD_READ error!");
427 }else{
428 // bug("%s",s->RxBuff);
431 //bug("Drain end\n");
435 if( s->SerTx ){
436 AbortIO((struct IORequest *)s->SerTx);
437 WaitIO((struct IORequest *)s->SerTx);
438 while(GetMsg(s->TxPort));
444 BOOL GetResponse(struct EasySerial *s,UBYTE *Buffer,ULONG maxbuffer,LONG timeout){
446 struct EasyTimer *t;
448 ULONG sigset;
449 BOOL result = FALSE;
450 char c[2]={0,0};
451 ULONG len = 0;
452 Buffer[0]=0;
454 if( ! s ) return FALSE;
455 if( ! s->Ok ) return FALSE;
457 bug("GetResponse:\n");
459 if( t = OpenTimer() ){
461 SetTimer(t,timeout);
463 QueueSerRequest( s , 1 );
464 if( ! s->Ok ){
465 CloseTimer(t);
466 return FALSE ;
469 for(;;){
471 sigset = (1L<< s->RxPort->mp_SigBit ) |
472 (1L<< t->TimeMsg->mp_SigBit );
474 Wait(sigset);
476 if( GetMsg( s->RxPort ) ){
478 if( len <= ( maxbuffer-1 ) ){
479 Buffer[len] = s->RxBuff[0];
480 c[0] = s->RxBuff[0];
481 bug( "%s" , c[0] == '\r' ? "<\\r>" :
482 c[0] == '\n' ? "<\\n>" :
485 if( Buffer[len] == '\r' ) Buffer[len] = '\n';
486 Buffer[++len] = 0;
487 if( strcasestr(Buffer,"OK\n") != NULL |
488 strcasestr(Buffer,"CONNECT") != NULL
490 result = TRUE;
491 break;
493 else if( strcasestr(Buffer,"NO CARRIER\n") != NULL |
494 strcasestr(Buffer,"ERROR\n") != NULL |
495 strcasestr(Buffer,"BUSY\n") != NULL
497 result = FALSE;
498 break;
503 QueueSerRequest( s , 1 );
504 if( ! s->Ok ){
505 CloseTimer(t);
506 return FALSE ;
510 if( GetMsg( t->TimeMsg ) ){
511 bug( "GetResponse TimeOut ERROR\n");
512 result = FALSE;
513 break;
517 CloseTimer(t);
520 if( s->SerRx ){
521 AbortIO((struct IORequest *)s->SerRx);
522 WaitIO((struct IORequest *)s->SerRx);
523 while(GetMsg(s->RxPort));
525 bug("GetResponse end\n");
526 return result;
531 struct EasySerial *OpenSerial(BYTE *name,ULONG unit){
532 struct EasySerial *s = NULL;
536 if( ! (s = AllocMem( sizeof(struct EasySerial),MEMF_CLEAR|MEMF_PUBLIC))) break;
537 if( ! (s->TxBuff = AllocMem( SERIAL_BUFSIZE ,MEMF_CLEAR|MEMF_PUBLIC))) break;
538 if( ! (s->RxBuff = AllocMem( SERIAL_BUFSIZE ,MEMF_CLEAR|MEMF_PUBLIC))) break;
539 if( ! (s->TxPort = CreateMsgPort())) break;
540 if( ! (s->SerTx = CreateIORequest(s->TxPort,sizeof(struct IOExtSer)))) break;
542 if( OpenDevice( name , unit , (struct IORequest *)s->SerTx,0)){
543 DeleteIORequest(s->SerTx);
544 s->SerTx = NULL;
545 break;
548 bug("OpenSerial:OpenDevice: \"%s\" unit %d\n",name,unit);
550 bug("Test CMD_WRITE\n");
551 s->SerTx->IOSer.io_Length = 0;
552 s->SerTx->IOSer.io_Data = " ";
553 s->SerTx->IOSer.io_Command = CMD_WRITE;
554 if( DoIO((struct IORequest *)s->SerTx)){
555 break;
558 if( ! (s->RxPort = CreateMsgPort()) ) break;
559 if( ! (s->SerRx = CreateIORequest(s->RxPort,sizeof(struct IOExtSer)))) break;
561 bug("Test SDCMD_QUERY\n");
562 s->SerRx->IOSer.io_Device = s->SerTx->IOSer.io_Device;
563 s->SerRx->IOSer.io_Unit = s->SerTx->IOSer.io_Unit;
564 s->SerRx->IOSer.io_Command = SDCMD_QUERY;
565 if( DoIO((struct IORequest *)s->SerRx)){
566 break;
569 D(bug("OpenSerial OK\n"));
570 s->Ok = TRUE;
571 return s;
573 }while(0);
575 // FAIL:
576 _CloseSerial(s);
577 return NULL;
581 VOID _CloseSerial(struct EasySerial *s){
583 if( ! s ) return ;
584 s->Ok = FALSE;
586 if( s->SerRx ){
587 AbortIO((struct IORequest *)s->SerRx);
588 WaitIO((struct IORequest *)s->SerRx);
589 while(GetMsg(s->RxPort));
592 if( s->SerTx ){
593 AbortIO((struct IORequest *)s->SerTx);
594 WaitIO((struct IORequest *)s->SerTx);
595 while(GetMsg(s->TxPort));
598 if(s->SerTx) CloseDevice((struct IORequest *)s->SerTx);
600 if(s->SerTx) DeleteIORequest(s->SerTx);
601 if(s->TxPort) DeleteMsgPort(s->TxPort);
603 if(s->SerRx) DeleteIORequest(s->SerRx);
604 if(s->RxPort) DeleteMsgPort(s->RxPort);
606 if( s->TxBuff ) FreeMem( s->TxBuff , SERIAL_BUFSIZE );
607 if( s->RxBuff ) FreeMem( s->RxBuff , SERIAL_BUFSIZE );
608 FreeMem( s , sizeof(struct EasySerial) );
613 VOID QueueSerRequest(struct EasySerial *s , LONG maxlength){
615 if( ! s ) return;
616 if( ! s->Ok ) return;
617 if( maxlength < 1 ) return;
619 if( maxlength > SERIAL_BUFSIZE ) maxlength = SERIAL_BUFSIZE;
620 s->SerRx->IOSer.io_Command = SDCMD_QUERY;
621 DoIO((struct IORequest *)s->SerRx);
623 if( s->SerRx->IOSer.io_Error ){
624 bug("QueueSerRequest() OOOOPS lost device!\n");
625 s->Ok = FALSE;
626 return;
629 s->SerRx->IOSer.io_Command = CMD_READ;
630 s->SerRx->IOSer.io_Data = s->RxBuff;
631 s->SerRx->IOSer.io_Length = s->SerRx->IOSer.io_Actual ;
633 if( s->SerRx->IOSer.io_Length > maxlength )
634 s->SerRx->IOSer.io_Length = maxlength;
635 /* If the number of bytes available is zero, queue a request
636 for one byte. */
637 if(!s->SerRx->IOSer.io_Length)
638 s->SerRx->IOSer.io_Length = 1;
640 SendIO((struct IORequest *)s->SerRx);
641 if( s->SerRx->IOSer.io_Error ){
642 bug("QueueSerRequest() SendIO -> CMD_READ error!");