📄 libprotocol.c
字号:
/* * $Id: libprotocol.c,v 1.12 1998/02/17 09:52:18 mdejonge Exp $ * * $Source: /home/mdejonge/CVS/projects/modem/libprotocol/libprotocol.c,v $ * $Revision: 1.12 $ * Author: Merijn de Jonge * Email: mdejonge@wins.uva.nl * * * * This file is part of the modem communication package. * Copyright (C) 1996-1998 Merijn de Jonge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <unistd.h>#include <stdio.h>#include <liberror/liberror.h>#include <libport/libport.h>#include "libprotocol.h"#include "modem_defs.h"typedef struct{ protType type; protHandler handler;} protHandlerItem;static protHandlerItem protHandlerList[] = { { PROT_DATA, NULL }, { PROT_COMMAND, NULL }, { PROT_REPLY, NULL }, { PROT_ERROR, NULL }};#define protHandlerListLength \ (sizeof ( protHandlerList ) / sizeof( protHandlerItem ) )typedef struct { protType type; unsigned length;} protRec;/* This protocol uses Big Endian byte ordering. The macro BigEndian is * used to convert Little endian to Bigendian and vice versa. */#ifdef BIG_ENDIAN#define BigEndian( x ) x#else#define BigEndian( x ) \ ( ( ((unsigned)x & 0xFF000000L) >> 24) & 0x000000FF)| \ ( ( ((unsigned)x & 0x00FF0000L) >> 8) & 0x0000FF00)| \ ( ((unsigned)x & 0x000000FFL) << 24) |\ ( ((unsigned)x & 0x0000FF00L) << 8) #endifstatic size_t writen( int fd, const void* vptr, size_t n ){ int nleft; int nwritten; const char* ptr; ptr = vptr; nleft = n; while( nleft > 0 ) { TEMP_FAILURE_RETRY( nwritten, write( fd, ptr, nleft ) ); if( nwritten <= 0 ) return nwritten; nleft -= nwritten; ptr += nwritten; } return n;}static size_t readn( int fd, void* vptr, size_t n ){ int nleft; int nread; char* ptr; ptr = vptr; nleft = n; while( nleft > 0 ) { TEMP_FAILURE_RETRY( nread, read( fd, ptr, nleft ) ); if( nread < 0 ) return nread; else if( nread == 0 ) break; nleft -= nread; ptr += nread; } return n - nleft;}int protConnectRequest( int fd ){ unsigned request_result; unsigned result; result = readn( fd, &request_result, sizeof request_result ); return BigEndian( request_result );} int protRequestConfirm( int fd, int request_result ){ unsigned result; unsigned request; request = BigEndian( request_result ); result = writen( fd, &request, sizeof request ); return result;}void protSetHandler( protType type, protHandler handler ){ int i; for( i = 0; i < protHandlerListLength; i++ ) { if( protHandlerList[i].type == protTypeOf( type ) ) { protHandlerList[i].handler = handler; break; } }}int protReceive( int fd ){ static char buf[protBufSize]; int result = -1; int i; protRec rec; int total = 0; result = readn( fd, &rec, sizeof rec ); /* Error or EOF */ if( result <= 0 ) return result; rec.type = BigEndian( rec.type ); rec.length = BigEndian( rec.length ); total += result; if( rec.length > protBufSize ) rec.length = protBufSize; /* Just for sure! */ result = 0; /* * Read returns immediately on some systems (Linux) when reading * 0 bytes. On other systems (SunOS) the read seems to block. */ if( rec.length > 0 ) do { i = readn( fd, buf + result, rec.length - result ); /* Error or EOF*/ if( i <= 0 ) return result; result += i; } while( result < rec.length ); /* Find prothandler and call if */ for( i = 0; i < protHandlerListLength; i++ ) { if( protTypeOf( rec.type ) == protHandlerList[i].type ) if( protHandlerList[i].handler != NULL ) { protHandlerList[i].handler( rec.type, buf, result ); break; } } total += result; return total;}int protSend( protType type, int fd, const void* data, size_t length ){ int result; int reclength; protRec rec; const char* ptr; /* Some compilers have problems working with void pointers */ ptr = (const char*)data; rec.type = BigEndian( type ); reclength = length; do { if( reclength > protBufSize ) rec.length = protBufSize; else rec.length = reclength; rec.length = BigEndian( rec.length ); result = writen( fd, &rec, sizeof rec ); /* Error or EOF */ if( result <= 0 ) return result; rec.length = BigEndian( rec.length ); result = writen( fd, ptr, rec.length ); /* Error or EOF */ if( result <= 0 ) return result; reclength -= result; ptr += rec.length; } while( reclength > 0 ); return length;}/* * EOF libprotocol/libprotocol.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -