⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modem.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include "modem.h"typedef struct {	char	*terse;	char	*verbose;	int	result;	int	(*f)(Modem*);} ResultCode;static ResultCode results[] = {	{ "0",	"OK",		Rok,		0, },	{ "1",	"CONNECT",	Rconnect,	0, },	{ "2",	"RING",		Rring,		0, },	{ "3",	"NO CARRIER", 	Rfailure,	0, },	{ "4",	"ERROR",	Rrerror,	0, },	{ "5",	"CONNECT 1200",	Rconnect,	0, },	{ "6",	"NO DIALTONE",	Rfailure,	0, },	{ "7",	"BUSY",		Rfailure,	0, },	{ "8",	"NO ANSWER",	Rfailure,	0, },	{ "9",	"CONNECT 2400",	Rconnect,	0, },		/* MT1432BA */	{ "10",	"CONNECT 2400",	Rconnect,	0, },		/* Hayes */	{ "11",	"CONNECT 4800",	Rconnect,	0, },	{ "12",	"CONNECT 9600",	Rconnect,	0, },	{ "13",	"CONNECT 14400",Rconnect,	0, },	{ "23",	"CONNECT 1275",	Rconnect,	0, },		/* MT1432BA */	{ "-1",	"+FCON",	Rcontinue,	fcon, },	{ "-1",	"+FTSI",	Rcontinue,	ftsi, },	{ "-1",	"+FDCS",	Rcontinue,	fdcs, },	{ "-1",	"+FCFR",	Rcontinue,	fcfr, },	{ "-1",	"+FPTS",	Rcontinue,	fpts, },	{ "-1",	"+FET",		Rcontinue,	fet, },	{ "-1",	"+FHNG",	Rcontinue,	fhng, },	{ 0 },};voidinitmodem(Modem *m, int fd, int cfd, char *type, char *id){	m->fd = fd;	m->cfd = cfd;	if(id == 0)		id = "Plan 9";	m->id = id;	m->t = type;}intrawmchar(Modem *m, char *p){	Dir *d;	int n;	if(m->icount == 0)		m->iptr = m->ibuf;	if(m->icount){		*p = *m->iptr++;		m->icount--;		return Eok;	}	m->iptr = m->ibuf;	if((d = dirfstat(m->fd)) == nil){		verbose("rawmchar: dirfstat: %r");		return seterror(m, Esys);	}	n = d->length;	free(d);	if(n == 0)		return Enoresponse;	if(n > sizeof(m->ibuf)-1)		n = sizeof(m->ibuf)-1;	if((m->icount = read(m->fd, m->ibuf, n)) <= 0){		verbose("rawmchar: read: %r");		m->icount = 0;		return seterror(m, Esys);	}	*p = *m->iptr++;	m->icount--;	return Eok;}intgetmchar(Modem *m, char *buf, long timeout){	int r, t;	timeout += time(0);	while((t = time(0)) <= timeout){		switch(r = rawmchar(m, buf)){		case Eok:			return Eok;		case Enoresponse:			sleep(100);			continue;		default:			return r;		}	}	verbose("getmchar: time %ud, timeout %ud", t, timeout);	return seterror(m, Enoresponse);}intputmchar(Modem *m, char *p){	if(write(m->fd, p, 1) < 0)		return seterror(m, Esys);	return Eok;}/* *  lines terminate with cr-lf */static intgetmline(Modem *m, char *buf, int len, long timeout){	int r, t;	char *e = buf+len-1;	char last = 0;	timeout += time(0);	while((t = time(0)) <= timeout){		switch(r = rawmchar(m, buf)){		case Eok:			/* ignore ^s ^q which are used for flow */			if(*buf == '\021' || *buf == '\023')				continue;			if(*buf == '\n'){				/* ignore nl if its not with a cr */				if(last == '\r'){					*buf = 0;					return Eok;				}				continue;			}			last = *buf;			if(*buf == '\r')				continue;			buf++;			if(buf == e){				*buf = 0;				return Eok;			}			continue;		case Enoresponse:			sleep(100);			continue;		default:			return r;		}	}	verbose("getmline: time %ud, timeout %ud", t, timeout);	return seterror(m, Enoresponse);}intcommand(Modem *m, char *s){	verbose("m->: %s", s);	if(fprint(m->fd, "%s\r", s) < 0)		return seterror(m, Esys);	return Eok;}/* * Read till we see a message or we time out. * BUG: line lengths not checked; *	newlines */intresponse(Modem *m, int timeout){	int r;	ResultCode *rp;	while(getmline(m, m->response, sizeof(m->response), timeout) == Eok){		if(m->response[0] == 0)			continue;		verbose("<-m: %s", m->response);		for(rp = results; rp->terse; rp++){			if(strncmp(rp->verbose, m->response, strlen(rp->verbose)))				continue;			r = rp->result;			if(rp->f && (r = (*rp->f)(m)) == Rcontinue)				break;			return r;		}	}	m->response[0] = 0;	return Rnoise;}voidxonoff(Modem *m, int i){	char buf[8];	sprint(buf, "x%d", i);	i = strlen(buf);	write(m->cfd, buf, i);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -