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

📄 cserialport.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************  CSerialPort.c  Network component  (c) 2003-2004 Daniel Campos Fernández <danielcampos@netcourrier.com>  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 1, 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.***************************************************************************/#define __CSERIALPORT_C#include <stdio.h>#include <termios.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/poll.h>#include <time.h>#ifdef __CYGWIN__/* Cygwin defines FIONREAD in <sys/socket.h>. */#include <sys/socket.h>#endif /* __CYGWIN__ */#include "main.h"#include "tools.h"#include "CSerialPort.h"#define MAX_SERIAL_BUFFER_SIZE 65536long *ser_objwatch=NULL;long *ser_portwatch=NULL;long ser_numwatch=0;GB_STREAM_DESC SerialStream = {	CSerialPort_stream_open,	CSerialPort_stream_close,	CSerialPort_stream_read,	CSerialPort_stream_write,	CSerialPort_stream_seek,	CSerialPort_stream_tell,	CSerialPort_stream_flush,	CSerialPort_stream_eof,	CSerialPort_stream_lof};DECLARE_EVENT (Serial_Read);DECLARE_EVENT (Serial_DTR);DECLARE_EVENT (Serial_DSR);DECLARE_EVENT (Serial_RTS);DECLARE_EVENT (Serial_CTS);DECLARE_EVENT (Serial_DCD);DECLARE_EVENT (Serial_RNG);void Serial_Signal_Status(serialsignal *sdata,int iPort){	int ist;	sdata->s_DSR=0;	sdata->s_DTR=0;	sdata->s_RTS=0;	sdata->s_CTS=0;	sdata->s_DCD=0;	sdata->s_RNG=0;	ioctl(iPort,TIOCMGET,&ist);	if ( ist & TIOCM_DSR ) sdata->s_DSR=1;	if ( ist & TIOCM_DTR ) sdata->s_DTR=1;	if ( ist & TIOCM_RTS ) sdata->s_RTS=1;	if ( ist & TIOCM_CTS ) sdata->s_CTS=1;	if ( ist & TIOCM_CAR ) sdata->s_DCD=1;	if ( ist & TIOCM_RNG ) sdata->s_RNG=1;}void CSerialPort_Event(long param){	serialevent *eparam;	eparam=(serialevent*)param;	switch(eparam->nevent)	{		case 0: GB.Raise(eparam->obj,Serial_DTR,1,GB_T_BOOLEAN,eparam->value); break;    		case 1: GB.Raise(eparam->obj,Serial_DSR,1,GB_T_BOOLEAN,eparam->value); break;    		case 2: GB.Raise(eparam->obj,Serial_RTS,1,GB_T_BOOLEAN,eparam->value); break;    		case 3: GB.Raise(eparam->obj,Serial_CTS,1,GB_T_BOOLEAN,eparam->value); break;    		case 4: GB.Raise(eparam->obj,Serial_DCD,1,GB_T_BOOLEAN,eparam->value); break;    		case 5: GB.Raise(eparam->obj,Serial_RNG,1,GB_T_BOOLEAN,eparam->value); break;	}	GB.Unref((void**)&eparam->obj);}void CSerialPort_CallBack(long lParam){	int position=0;	serialsignal newstatus;	struct pollfd mypoll;	int numpoll;	CSERIALPORT *mythis;	/*	Just sleeping a little to reduce CPU waste	*/	struct timespec mywait;	mywait.tv_sec=0;	mywait.tv_nsec=1000000;	nanosleep(&mywait,NULL);	if ((position=search_by_integer(ser_portwatch,ser_numwatch,(int)lParam))==-1) return;	mythis=(CSERIALPORT*)ser_objwatch[position];	/* Serial port signals status */	Serial_Signal_Status(&newstatus,lParam);	mythis->e_DTR.value=newstatus.s_DTR;	mythis->e_DSR.value=newstatus.s_DSR;	mythis->e_RTS.value=newstatus.s_RTS;	mythis->e_CTS.value=newstatus.s_CTS;	mythis->e_DCD.value=newstatus.s_DCD;	mythis->e_RNG.value=newstatus.s_RNG;	if (mythis->ser_status.s_DTR != newstatus.s_DTR ) {		mythis->ser_status.s_DTR = newstatus.s_DTR;		GB.Ref(mythis);		GB.Post(CSerialPort_Event,(long)&mythis->e_DTR);	}	if (mythis->ser_status.s_DSR != newstatus.s_DSR ) {		mythis->ser_status.s_DSR = newstatus.s_DSR;		GB.Ref(mythis);		GB.Post(CSerialPort_Event,(long)&mythis->e_DSR);	}	if (mythis->ser_status.s_RTS != newstatus.s_RTS ) {		mythis->ser_status.s_RTS = newstatus.s_RTS;		GB.Ref(mythis);		GB.Post(CSerialPort_Event,(long)&mythis->e_RTS);	}	if (mythis->ser_status.s_CTS != newstatus.s_CTS ) {		mythis->ser_status.s_CTS = newstatus.s_CTS;		GB.Ref(mythis);		GB.Post(CSerialPort_Event,(long)&mythis->e_CTS);	}	if (mythis->ser_status.s_DCD != newstatus.s_DCD ) {		mythis->ser_status.s_DCD = newstatus.s_DCD;		GB.Ref(mythis);		GB.Post(CSerialPort_Event,(long)&mythis->e_DCD);	}	if (mythis->ser_status.s_RNG != newstatus.s_RNG ) {		mythis->ser_status.s_RNG = newstatus.s_RNG;		GB.Ref(mythis);		GB.Post(CSerialPort_Event,(long)&mythis->e_RNG);	}	/* Data Available */	mypoll.fd=lParam;	mypoll.events=POLLIN;	mypoll.revents=0;	numpoll=poll(&mypoll,1,0);	if (numpoll)	{		GB.Raise((void*)mythis,Serial_Read,0);	}}void CSerialPort_AssignCallBack(long t_obj,int t_port){	int position=0;	CSERIALPORT *mythis;	mythis=(CSERIALPORT*)t_obj;	position=search_by_integer(ser_objwatch,ser_numwatch,t_obj);	if (position>=0)		GB.Watch (t_port , GB_WATCH_NONE , (void *)CSerialPort_CallBack,0);	if (position<0)	{		position=ser_numwatch++;		Alloc_CallBack_Pointers(ser_numwatch,&ser_objwatch,&ser_portwatch);	}	ser_objwatch[position]=t_obj;	ser_portwatch[position]=t_port;	GB.Watch (t_port , GB_WATCH_WRITE , (void *)CSerialPort_CallBack,0);}void CSerialPort_FreeCallBack(long t_obj){	int myloop;	int position;	position=search_by_integer(ser_objwatch,ser_numwatch,t_obj);	if ( position==-1 ) return;	GB.Watch (ser_portwatch[position] , GB_WATCH_NONE , (void *)CSerialPort_CallBack,0);	for ( myloop=position;myloop < (ser_numwatch-1);myloop++ )	{		ser_objwatch[myloop]=ser_objwatch[myloop+1];		ser_portwatch[myloop]=ser_portwatch[myloop+1];	}	ser_numwatch--;	Alloc_CallBack_Pointers(ser_numwatch,&ser_objwatch,&ser_portwatch);}//////////////////////////////////////////////////////////////////////////////////////////**********************************************************************************//===================================================================================//##################STREAM RELATED FUNCTIONS#########################################//===================================================================================//***********************************************************************************/////XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX///////////////////////////////////////////////////////////////////////////////////////int CSerialPort_stream_open(GB_STREAM *stream, const char *path, int mode, void *data){	return -1; /* not allowed */}int CSerialPort_stream_seek(GB_STREAM *stream, long pos, int whence){	return -1; /* not allowed */}int CSerialPort_stream_tell(GB_STREAM *stream, long *pos){	return -1; /* not allowed */}int CSerialPort_stream_flush(GB_STREAM *stream){	return 0; /* OK */}int CSerialPort_stream_close(GB_STREAM *stream){	CSERIALPORT *mythis;	if (!(mythis=(CSERIALPORT*)stream->_free[0])) return -1;			if (mythis->iStatus)	{		CSerialPort_FreeCallBack((long)mythis);		mythis->stream.desc=NULL;		CloseSerialPort(mythis->Port,&mythis->oldtio);		mythis->iStatus=0;	}	return 0;}int CSerialPort_stream_lof(GB_STREAM *stream, long *len){	CSERIALPORT *mythis;	int bytes;	*len=0;	if (!(mythis=(CSERIALPORT*)stream->_free[0])) return -1;		if (ioctl(mythis->Port,FIONREAD,&bytes)) return -1;	*len=bytes;	return 0;}int CSerialPort_stream_eof(GB_STREAM *stream){	CSERIALPORT *mythis;	int bytes;	if (!(mythis=(CSERIALPORT*)stream->_free[0])) return -1;		if (ioctl(mythis->Port,FIONREAD,&bytes)) return -1;	if (!bytes) return -1;	return 0;}int CSerialPort_stream_read(GB_STREAM *stream, char *buffer, long len){	CSERIALPORT *mythis;  	int npos=-1;  	int NoBlock=0;	int bytes;  	if (!(mythis=(CSERIALPORT*)stream->_free[0])) return -1;		if (ioctl(mythis->Port,FIONREAD,&bytes)) return -1;	if (bytes < len) return -1;	ioctl(mythis->Port,FIONBIO,&NoBlock);	npos=read(mythis->Port,(void*)buffer,len);	NoBlock++;  	ioctl(mythis->Port,FIONBIO,&NoBlock);  	if (npos==len) return 0;  	return -1;}int CSerialPort_stream_write(GB_STREAM *stream, char *buffer, long len){	CSERIALPORT *mythis;	int npos=-1;	int NoBlock=0;	if (!(mythis=(CSERIALPORT*)stream->_free[0])) return -1;		ioctl(mythis->Port,FIONBIO,&NoBlock);	npos=write(mythis->Port,(void*)buffer,len);	NoBlock++;	ioctl(mythis->Port,FIONBIO,&NoBlock);	if (npos>=0) return 0;	return -1;}/************************************************************************##########################################################################				GAMBAS OBJECT PUBLIC INTERFACE##########################################################################**************************************************************************//********************************************************************Returns current Status of the port (0->Closed, 1 --> Opened)*********************************************************************/BEGIN_PROPERTY ( CSERIALPORT_Status )  GB.ReturnInteger(THIS->iStatus);END_PROPERTY/************************************* Data Set Ready *************************************/BEGIN_PROPERTY ( CSERIALPORT_DSR )  if ( !THIS->iStatus )  {  	GB.ReturnBoolean(0);	return;  }  Serial_Signal_Status(&THIS->ser_status,THIS->Port);  GB.ReturnBoolean(THIS->ser_status.s_DSR);END_PROPERTY/*************************************** Data Transmission Ready ***************************************/BEGIN_PROPERTY ( CSERIALPORT_DTR )	int ist;	if (READ_PROPERTY)	{		if ( !THIS->iStatus )		{			GB.ReturnBoolean(0);			return;		}		Serial_Signal_Status(&THIS->ser_status,THIS->Port);		GB.ReturnBoolean(THIS->ser_status.s_DTR);		return;	}  	if (!THIS->iStatus )	{		GB.Error ("Port is Closed.");		return;	}	ioctl(THIS->Port,TIOCMGET,&ist);	if (!VPROP(GB_BOOLEAN))		ist &= ~TIOCM_DTR;	else		ist = ist | TIOCM_DTR;	ioctl(THIS->Port,TIOCMSET,&ist);END_PROPERTY

⌨️ 快捷键说明

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