/* Copyright (C) 2001 ITK Authors : Paul Lasarev License : (GPL) http://www.itk.ru/clipper/license.html */ /* $Log: com.c,v $ Revision 1.5 2005/08/09 08:49:09 clip alena: fix for gcc 4 Revision 1.4 2004/05/28 12:34:55 clip uri: add com_rts() Revision 1.3 2002/06/24 10:03:00 clip don't know what Revision 1.2 2002/02/07 12:34:02 clip open mode fix paul Revision 1.1 2002/02/07 11:44:27 clip initial paul */ #include #include #include #include "hashcode.h" #include "clip.h" #include "error.ch" #include "libezV24/ezV24.h" static void destroy_com_port(void *port) { if (port) v24ClosePort((v24_port_t *) port); } static int keys[32]; int clip_COM_NUM(ClipMachine * mp) { unsigned long bitmask = 0; int r; r = v24CountPorts(&bitmask); if (r < 0) return _clip_trap_err(mp, EG_UNSUPPORTED, 0, 0, __FILE__, __LINE__, "COM_NUM"); _clip_retni(mp, r + 1); return 0; } /* COM_OPEN(nPort|cDevice,[dontused],[dontused],[dontused],l_RTSCTS,l_XONXOFF,lDebug) */ int clip_COM_OPEN(ClipMachine * mp) { int no = _clip_parni(mp, 1); char *dev = _clip_parc(mp, 1); char buf[V24_SZ_PORTNAME]; int ctsrts = _clip_parl(mp, 5); int xonxoff = _clip_parl(mp, 6); int dbg = _clip_parl(mp, 7); v24_port_t *gz; int *err, k; if (!_clip_parinfo(mp, 5) && !!_clip_parinfo(mp, 5)) ctsrts = 1; if (!dev && (no < 1 || no > 32)) return EG_ARG; if (!dev) { v24PortName(no - 1, buf); dev = buf; } gz = v24OpenPort(dev, V24_STANDARD | V24_LOCK /*| V24_NO_DELAY*/ | (ctsrts ? V24_RTS_CTS : 0) | (xonxoff ? V24_XON_XOFF : 0) | V24_DROP_DTR | (dbg ? V24_DEBUG_ON : 0) ); if (!gz) { err = _clip_fetch_item(mp, HASH_ferror); *err = errno; _clip_retl(mp, 0); return 0; } k = _clip_store_c_item(mp, gz, _C_ITEM_TYPE_FILE, destroy_com_port); keys[no] = k; _clip_retl(mp, 1); return 0; } int clip_COM_CLOSE(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); int ret = -1, *err = _clip_fetch_item(mp, HASH_ferror); if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (gz == NULL) return EG_ARG; else if (_clip_destroy_c_item(mp, fd, _C_ITEM_TYPE_FILE)) { ret = 0; *err = 0; } _clip_retl(mp, (ret == 0)); return 0; } static int baud_val(int baud) { switch (baud) { default: return V24_B9600; case 0: return V24_B0; case 50: return V24_B50; case 75: return V24_B75; case 110: return V24_B110; case 134: return V24_B134; case 150: return V24_B150; case 200: return V24_B200; case 300: return V24_B300; case 600: return V24_B600; case 1200: return V24_B1200; case 1800: return V24_B1800; case 2400: return V24_B2400; case 4800: return V24_B4800; case 9600: return V24_B9600; case 19200: return V24_B19200; case 38400: return V24_B38400; case 57600: return V24_B57600; case 115200: return V24_B115200; } } static int data_val(int data) { switch (data) { case 5: return V24_5BIT; case 6: return V24_6BIT; case 7: return V24_7BIT; default: case 8: return V24_8BIT; } } static int parity_val(char *p) { if (!p || !*p) return V24_NONE; switch (toupper(p[0])) { case 'N': default: return V24_NONE; case 'E': return V24_EVEN; case 'O': return V24_ODD; case 'I': return V24_IGNORE; } } /* COM_INIT(,[],[], [],[]) --> lInitialized */ int clip_COM_INIT(ClipMachine * mp) { v24_port_t *gz; int ret = -1, *err; int fd = _clip_parni(mp, 1); int baud = 9600, data = 8, stop = 1; char *parity = "N"; if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (!gz) return EG_ARG; if (_clip_parinfo(mp, 2) == NUMERIC_t) baud = _clip_parni(mp, 2); if (_clip_parinfo(mp, 3) == CHARACTER_t) parity = _clip_parc(mp, 3); if (_clip_parinfo(mp, 4) == NUMERIC_t) data = _clip_parni(mp, 4); if (_clip_parinfo(mp, 5) == NUMERIC_t) stop = _clip_parni(mp, 5); err = _clip_fetch_item(mp, HASH_ferror); ret = v24SetParameters(gz, baud_val(baud), data_val(data), parity_val(parity)); _clip_retl(mp, ret ? 0 : 1); return 0; } /* COM_TIMEOUT(,[ nOldTimeout nTimeout in 1/10 sec */ int clip_COM_TIMEOUT(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); int to = _clip_parni(mp, 2); int oto; if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (gz == NULL) { return EG_ARG; } oto = gz->TimeoutValue; if (mp->argc > 1) { v24SetTimeouts(gz, to); } _clip_retni(mp, oto); return 0; } /* COM_SEND(,) --> nLength return length of UNSENDED data */ int clip_COM_SEND(ClipMachine * mp) { v24_port_t *gz; int len = 0, *err = NULL; int fd = _clip_parni(mp, 1); char *sptr = NULL, buf[2], *str = _clip_parcl(mp, 2, &len); long ret = -1; if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (_clip_parinfo(mp,2)== NUMERIC_t) { buf[0] = (char) _clip_parni(mp,2); buf[1] = 0; len = 1 ; sptr = buf; } else sptr = str; if (gz == NULL || !sptr) { return EG_ARG; } ret = v24Write(gz, (unsigned char *)sptr, len); err = _clip_fetch_item(mp, HASH_ferror); *err = ret < 0 ? errno : 0; _clip_retni(mp, (len - ret)); return 0; } int clip_COM_READ(ClipMachine * mp) { v24_port_t *gz; char *buf; int *err = NULL, fd, nb = 0; long ret = -1; fd = _clip_parni(mp, 1); nb = _clip_parni(mp, 2); if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (gz == NULL) return EG_ARG; if (!nb) nb = 1024; buf = (char *) malloc(nb); ret = v24Read(gz, (unsigned char *)buf, nb); if (ret < 0) { err = _clip_fetch_item(mp, HASH_ferror); *err = errno; ret = 0; if (gz->Errno != V24_E_OK) { free(buf); return EG_READ; } } buf = (char *) realloc(buf, ret + 1); buf[ret] = 0; _clip_retcn_m(mp, buf, ret); return 0; } /* COM_FLUSH() --> lClear */ int clip_COM_FLUSH(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (!gz) return (EG_ARG); _clip_retl(mp, v24FlushRxQueue(gz) ? 0 : 1); return 0; } /* COM_SFLUSH() --> lDeleted */ int clip_COM_SFLUSH(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (!gz) return (EG_ARG); _clip_retl(mp, v24FlushTxQueue(gz) ? 0 : 1); return 0; } /* COM_SOFT(,[],[], []) --> lOldHandshake */ int clip_COM_SOFT(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); int flag = _clip_parl(mp, 2); int oflag; if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (!gz) return (EG_ARG); oflag = gz->OpenFlags & V24_XON_XOFF; if (mp->argc > 1) { if (flag) gz->OpenFlags |= V24_XON_XOFF; else gz->OpenFlags &= ~V24_XON_XOFF; v24SetParameters(gz, gz->Baudrate, gz->Datasize, gz->Parity); } _clip_retl(mp, oflag ? 1 : 0); return 0; } /* COM_HARD(,,[]) --> lOldHandshake */ int clip_COM_HARD(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); int flag = _clip_parl(mp, 2); int oflag; if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (!gz) return (EG_ARG); oflag = gz->OpenFlags & V24_RTS_CTS; if (mp->argc > 1) { if (flag) gz->OpenFlags |= V24_RTS_CTS; else gz->OpenFlags &= ~V24_RTS_CTS; v24SetParameters(gz, gz->Baudrate, gz->Datasize, gz->Parity); } _clip_retl(mp, oflag ? 1 : 0); return 0; } /* COM_DTR(,[]) --> lOldDTRStatus note - really returns success code */ int clip_COM_DTR(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); int flag = _clip_parl(mp, 2); int oflag; if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (!gz) return (EG_ARG); oflag = 0; if (mp->argc > 1) { oflag = v24SetDTR(gz, flag); } _clip_retl(mp, oflag ? 0 : 1); return 0; } int clip_COM_RTS(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); int flag = _clip_parl(mp, 2); int oflag; if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (!gz) return (EG_ARG); oflag = 0; if (mp->argc > 1) { oflag = v24SetRTS(gz, flag); } _clip_retl(mp, oflag ? 0 : 1); return 0; } /* COM_COUNT() --> nTotalCharacters */ int clip_COM_COUNT(ClipMachine * mp) { v24_port_t *gz; int fd = _clip_parni(mp, 1); int n; if (fd < 1 || fd > 32) return EG_ARG; fd = keys[fd]; gz = (v24_port_t *) _clip_fetch_c_item(mp, fd, _C_ITEM_TYPE_FILE); if (!gz) return (EG_ARG); n = v24HaveData(gz); _clip_retni(mp, n); return 0; }