home *** CD-ROM | disk | FTP | other *** search
- #include "/include/memory.h"
-
- #include "dialer.h"
-
- /*
- * note that you probably don't want to have both debug's turned on at the
- * same time...
- */
-
- /* #define DEBUG_WRITES */
- /* #define DEBUG_READS */
-
- /* storage for various magic items */
-
- static struct IOExtSer SerialRead;
- static struct IOExtSer SerialWrite;
- static struct MsgPort *SReadPort;
- static struct MsgPort *SWritePort;
- static ULONG SReadSigMask;
- static ULONG SWriteSigMask;
- static BOOL SerialUp = FALSE;
-
- static UBYTE SReadBuf[256];
- static ULONG SReadPos;
- static ULONG SReadSize;
-
- static UBYTE SWriteBuf[256];
- static ULONG SWritePos;
-
- /* hold some magic info */
-
- static struct MsgPort *TimerPort;
- struct timerequest TimerIO;
- ULONG TimerSigMask;
- BOOL TimerUp = FALSE;
-
- /* open up the timer for use */
-
- static BOOL OpenTimer(void)
- {
- if (!(TimerPort = CreatePort(NULL, 0)))
- return FALSE;
-
- TimerSigMask = 1L << TimerPort->mp_SigBit;
-
- if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)&TimerIO, 0)) {
- DeletePort(TimerPort);
- return FALSE;
- }
-
- TimerIO.tr_node.io_Message.mn_ReplyPort = TimerPort;
-
- TimerUp = TRUE;
-
- return TRUE;
- }
-
- /* shut down our timer handling stuff */
-
- static void CloseTimer(void)
- {
- if (TimerUp) {
- CloseDevice((struct IORequest *)&TimerIO);
- DeletePort(TimerPort);
- TimerUp = FALSE;
- }
- }
-
- typedef struct {
- STRPTR mi_Device;
- ULONG mi_Unit;
- ULONG mi_MaxBaud;
- BOOL mi_MatchDTE;
- BOOL mi_CTSRTS;
- UBYTE mi_ModemInit[1];
- }
- ModemInfo_t;
-
- ModemInfo_t *openedMi = NULL;
-
- ULONG currentBaud;
- BOOL use8N1;
-
- /* try and OpenDevice() and set the appropriate serial parameters */
-
- static BOOL InitSer(ModemInfo_t * mi)
- {
- register struct IOExtSer *ior = &SerialRead;
- register struct IOExtSer *iow = &SerialWrite;
-
- /* try and open the device */
- ior->io_SerFlags = 0;
- if (mi->mi_CTSRTS)
- ior->io_SerFlags |= SERF_7WIRE;
- else
- ior->io_SerFlags &= ~SERF_7WIRE;
-
- ior->IOSer.io_Message.mn_ReplyPort = SReadPort;
-
- if (OpenDevice(openedMi->mi_Device, openedMi->mi_Unit, (struct IORequest *)ior, 0)) {
- return FALSE;
- }
-
- ior->IOSer.io_Command = SDCMD_QUERY;
- DoIO((struct IORequest *)ior);
-
- /*
- * supposedly you are only allowed to set SERF_7WIRE before you open
- * the device. However, it seems that the oldser.device used by the
- * A2232 is screwing this up. So we reset it after out open device
- * call just in case.
- */
-
- if (mi->mi_CTSRTS)
- ior->io_SerFlags |= SERF_7WIRE;
- else
- ior->io_SerFlags &= ~SERF_7WIRE;
-
- ior->io_Baud = currentBaud;
- ior->io_StopBits = 1;
- ior->io_RBufLen = 1024;
-
- if (use8N1) {
- ior->io_ReadLen = ior->io_WriteLen = 8;
- ior->io_SerFlags &= ~(SERF_PARTY_ODD | SERF_PARTY_ON | SERF_XDISABLED); /* insure no parity is
- * in use */
- }
- else {
- ior->io_ReadLen = ior->io_WriteLen = 7;
- ior->io_SerFlags &= ~(SERF_PARTY_ODD | SERF_XDISABLED);
- ior->io_SerFlags |= SERF_PARTY_ON;
- ior->io_ExtFlags &= ~SEXTF_MSPON;
- };
-
- ior->IOSer.io_Command = SDCMD_SETPARAMS;
- if (DoIO((struct IORequest *)ior)) {
- CloseDevice((struct IORequest *)&SerialRead);
- return FALSE;
- }
-
- CopyMem((APTR)ior, (APTR)iow, sizeof(struct IOExtSer));
-
- iow->IOSer.io_Message.mn_ReplyPort = SWritePort;
-
- SReadPos = SReadSize = 0;
-
- SerialUp = TRUE;
-
- return TRUE;
- }
-
- /* open up the serial device */
-
- static BOOL OpenSerial(ModemInfo_t * mi, BOOL AttemptMode)
- {
- STRPTR ODUresult;
-
- /* save these away for when we need to close the device */
-
- openedMi = mi;
-
- /* allocate our message ports */
- if (!(SReadPort = CreatePort(NULL, 0))) {
- openedMi = NULL;
- return FALSE;
- }
-
- if (!(SWritePort = CreatePort(NULL, 0))) {
- DeletePort(SReadPort);
- openedMi = NULL;
- return FALSE;
- }
-
- SReadSigMask = 1L << SReadPort->mp_SigBit;
- SWriteSigMask = 1L << SWritePort->mp_SigBit;
-
- if (AttemptMode)
- ODUresult = AttemptDevUnit(openedMi->mi_Device, openedMi->mi_Unit, PROGNAME, 0L);
- else
- ODUresult = LockDevUnit(openedMi->mi_Device, openedMi->mi_Unit, PROGNAME, 0L);
-
- if (ODUresult) {
- DeletePort(SWritePort);
- DeletePort(SReadPort);
- openedMi = NULL;
- return FALSE;
- }
-
- currentBaud = mi->mi_MaxBaud;
- use8N1 = FALSE;
-
- if (!InitSer(mi)) {
- FreeDevUnit(openedMi->mi_Device, openedMi->mi_Unit);
-
- DeletePort(SWritePort);
- DeletePort(SReadPort);
- openedMi = NULL;
- return FALSE;
- }
-
- if (!OpenTimer()) {
- CloseSerial();
- return FALSE;
- }
-
- return TRUE;
- }
-
- /* this expects that the baud rate passed in is the baud rate of the service */
-
- void SwitchBaud(ULONG baud)
- {
- currentBaud = baud;
-
- if (openedMi->mi_MatchDTE) {
- if (baud > openedMi->mi_MaxBaud)
- baud = openedMi->mi_MaxBaud;
- }
- else
- baud = openedMi->mi_MaxBaud;
-
- SerialRead.io_Baud = baud;
- SerialRead.IOSer.io_Command = SDCMD_SETPARAMS;
- DoIO((struct IORequest *)&SerialRead);
-
- SerialWrite.io_Baud = baud;
- SerialWrite.IOSer.io_Command = SDCMD_SETPARAMS;
- DoIO((struct IORequest *)&SerialWrite);
- }
-
- BOOL Connected(void)
- {
- SerialRead.IOSer.io_Command = SDCMD_QUERY;
- DoIO((struct IORequest *)&SerialRead);
-
- if (SerialRead.io_Status & (1L << 5))
- return FALSE;
- else
- return TRUE;
- }
-
- #define MODEM_TEMPLATE "DEVICE/A,UNIT/N/A,MAXBAUD/N/A,MATCHDTE/A,CTSRTS/A,INITSTRING/A"
- enum ModemArgs {
- ARG_DEVICE,
- ARG_UNIT,
- ARG_BAUD,
- ARG_DTE,
- ARG_CTS,
- ARG_INIT,
- ARG_sizeof
- };
-
- static ModemInfo_t *ReadModemInfo(LONG modemNumber)
- {
- ModemInfo_t *mi = NULL;
- UBYTE modemName[32];
- STRPTR modemConfig;
- STRPTR buffer;
- struct RDArgs *ArgsPtr;
- struct RDArgs *MyArgs;
- STRPTR ArgArray[ARG_sizeof];
-
- sprintf(modemName, "MODEM%ld", modemNumber);
-
- if (modemNumber == 1)
- modemConfig = FindPagerConfigDefault(ph, modemName, "serial.device 0 1200 y n ATZ\\r\\d\\d\\dATM0\\r\\dATD");
- else
- modemConfig = FindPagerConfig(ph, modemName);
-
- if (modemConfig) {
- if (buffer = MyAllocVec(strlen(modemConfig) + 4)) {
- strcpy(buffer, modemConfig);
- strcat(buffer, "\n");
-
- if (MyArgs = (struct RDArgs *)AllocDosObject(DOS_RDARGS, TAG_DONE)) {
- MyArgs->RDA_Flags |= RDAF_NOPROMPT;
- MyArgs->RDA_Source.CS_Buffer = buffer;
- MyArgs->RDA_Source.CS_Length = strlen(buffer);
- MyArgs->RDA_Source.CS_CurChr = 0L;
-
- memset((char *)ArgArray, 0, sizeof(ArgArray));
- if (ArgsPtr = ReadArgs(MODEM_TEMPLATE, (LONG *)&ArgArray, MyArgs)) {
- if (mi = (ModemInfo_t *) MyAllocVec(sizeof(ModemInfo_t) + strlen(ArgArray[ARG_DEVICE]) + strlen(ArgArray[ARG_INIT]) + 2)) {
- strcpy(mi->mi_ModemInit, ArgArray[ARG_INIT]);
-
- mi->mi_Device = &mi->mi_ModemInit[strlen(mi->mi_ModemInit) + 1];
- strcpy(mi->mi_Device, ArgArray[ARG_DEVICE]);
-
- mi->mi_Unit = *((LONG *)ArgArray[ARG_UNIT]);
- mi->mi_MaxBaud = *((LONG *)ArgArray[ARG_BAUD]);
- mi->mi_MatchDTE = PagerConfigYesNo(ArgArray[ARG_DTE]);
- mi->mi_CTSRTS = PagerConfigYesNo(ArgArray[ARG_CTS]);
- }
- else
- ErrorMsg("out of memory!");
-
- FreeArgs(ArgsPtr);
- }
- else {
- ErrorMsg("%s config entry badly formatted.", modemName);
- ULog(ph, -1, "%s config entry badly formatted.", modemName);
- }
-
- FreeDosObject(DOS_RDARGS, MyArgs);
- }
- else
- ErrorMsg("out of memory!");
-
- MyFreeVec(buffer);
- }
- else
- ErrorMsg("out of memory!");
-
- FreePagerConfig(modemConfig);
- }
-
- return mi;
- }
-
- LONG OpenModem(LONG modemNumber, LONG modemStart)
- {
- ModemInfo_t *mi;
-
- online = FALSE;
-
- if (modemNumber) {
- if (mi = ReadModemInfo(modemNumber)) {
- if (OpenSerial(mi, FALSE) == FALSE) {
- MyFreeVec(mi);
- return 0L;
- }
- else
- return modemNumber;
- }
- }
- else {
- modemNumber = modemStart;
-
- while (mi = ReadModemInfo(modemNumber++))
- if (OpenSerial(mi, TRUE))
- return modemNumber - 1;
-
- return 0L;
- }
- }
-
- /* close down the serial handling stuff */
-
- void CloseSerial(void)
- {
- CloseTimer();
-
- if (SerialUp) {
- CloseDevice((struct IORequest *)&SerialRead);
- online = SerialUp = FALSE;
- }
-
- FreeDevUnit(openedMi->mi_Device, openedMi->mi_Unit);
-
- MyFreeVec(openedMi);
- openedMi = NULL;
-
- DeletePort(SWritePort);
- DeletePort(SReadPort);
- }
-
- /* hang up the modem -- we use a DTR drop to do this */
- BOOL HangUp(void)
- {
- if (SerialUp) {
- CloseDevice((struct IORequest *)&SerialRead);
- online = SerialUp = FALSE;
- }
-
- Delay(TICKS_PER_SECOND);
-
- return InitSer(openedMi);
- }
-
- /* determine if we should be using 8N1 or 7E1 */
- BOOL Use8N1(BOOL set8N1)
- {
- BOOL old8N1;
-
- old8N1 = use8N1;
-
- use8N1 = set8N1;
-
- /*
- * if they really changed the use8N1 state then we need to check to
- * see if the modem is currently on-line and reset it if so.
- */
-
- if (use8N1 != old8N1) {
- if (SerialUp) {
- CloseDevice((struct IORequest *)&SerialRead);
- online = SerialUp = FALSE;
- }
-
- Delay(TICKS_PER_SECOND);
-
- return InitSer(openedMi);
- }
- else
- return TRUE;
- }
-
- /* flush out the serial read buffer */
-
- void ClearSerial(void)
- {
- SReadPos = SReadSize = 0;
-
- SerialRead.IOSer.io_Command = CMD_CLEAR;
- DoIO((struct IORequest *)&SerialRead);
- }
-
- /* send a string to the serial device */
-
- void SerWrite(STRPTR Buf, ULONG Len)
- {
- #ifdef DEBUG_WRITES
- FWrite(Output(), Buf, 1, Len);
- #endif
-
- SerialWrite.IOSer.io_Command = CMD_WRITE;
- SerialWrite.IOSer.io_Length = Len;
- SerialWrite.IOSer.io_Data = (APTR)Buf;
- DoIO((struct IORequest *)&SerialWrite);
-
- if (SerialWrite.IOSer.io_Error)
- ULog(ph, -1, "serial write error %ld", SerialWrite.IOSer.io_Error);
- }
-
- void SerPutChar(UBYTE value)
- {
- UBYTE Buf[2];
-
- #ifdef DEBUG_WRITES
- FPutC(Output(), value);
- #endif
-
- Buf[0] = value;
-
- SerialWrite.IOSer.io_Command = CMD_WRITE;
- SerialWrite.IOSer.io_Length = 1;
- SerialWrite.IOSer.io_Data = (APTR)Buf;
- DoIO((struct IORequest *)&SerialWrite);
-
- if (SerialWrite.IOSer.io_Error)
- ULog(ph, -1, "serial write error %ld", SerialWrite.IOSer.io_Error);
- }
-
- /*
- * wait for a specific string to be read from the device. this is
- * case-insensitive
- */
-
- BOOL SerWaitString(STRPTR target, LONG timeout)
- {
- UWORD byteRead;
- int i, len;
-
- len = strlen(target);
- i = 0;
-
- while ((byteRead = SerGetRawChar(timeout)) != TIMEOUT) {
- if (tolower(byteRead) == tolower(target[i])) {
- if (++i == len)
- return TRUE;
- }
- else
- i = 0;
- }
-
- return FALSE;
- }
-
- /* get a character from the serial device with a timeout */
-
- UWORD SerGetRawChar(LONG timeout)
- {
- UBYTE Buffer[2];
- ULONG Signals;
- ULONG secs, micro;
-
- if (timeout < 0) {
- secs = 0;
- micro = -timeout;
- }
- else {
- secs = timeout;
- micro = 0;
- }
-
- if (SReadPos < SReadSize) {
- #ifdef DEBUG_READS
- Printf("%lc", SReadBuf[SReadPos]);
- #endif
- return (UWORD)SReadBuf[SReadPos++];
- }
-
- SetSignal(0L, SReadSigMask | TimerSigMask);
-
- SerialRead.IOSer.io_Command = CMD_READ;
- SerialRead.IOSer.io_Length = 1;
- SerialRead.IOSer.io_Data = (APTR)Buffer;
- SendIO((struct IORequest *)&SerialRead);
-
- TimerIO.tr_node.io_Command = TR_ADDREQUEST;
- TimerIO.tr_time.tv_secs = secs;
- TimerIO.tr_time.tv_micro = micro;
- SendIO((struct IORequest *)&TimerIO);
-
- Signals = Wait(SReadSigMask | TimerSigMask);
-
- if (Signals & SReadSigMask) {
- if (!CheckIO((struct IORequest *)&TimerIO)) {
- AbortIO((struct IORequest *)&TimerIO);
- }
- WaitIO((struct IORequest *)&TimerIO);
-
- WaitIO((struct IORequest *)&SerialRead);
-
- if (!SerialRead.IOSer.io_Error && SerialRead.IOSer.io_Actual) {
- SerialRead.IOSer.io_Command = SDCMD_QUERY;
- DoIO((struct IORequest *)&SerialRead);
-
- if (SerialRead.IOSer.io_Actual) {
- SerialRead.IOSer.io_Command = CMD_READ;
- SerialRead.IOSer.io_Length = min(sizeof(SReadBuf), SerialRead.IOSer.io_Actual);
- SerialRead.IOSer.io_Data = (APTR)SReadBuf;
- DoIO((struct IORequest *)&SerialRead);
-
- if (!SerialRead.IOSer.io_Error) {
- SReadPos = 0;
- SReadSize = SerialRead.IOSer.io_Actual;
- }
- }
-
- #ifdef DEBUG_READS
- Printf("%lc", Buffer[0]);
- #endif
- return (UWORD)Buffer[0];
- }
- else
- return 0;
- }
-
- if (Signals & TimerSigMask)
- WaitIO((struct IORequest *)&TimerIO);
-
- /* if we get down here we have timed out waiting for a character */
-
- if (!CheckIO((struct IORequest *)&SerialRead)) {
- AbortIO((struct IORequest *)&SerialRead);
- }
- WaitIO((struct IORequest *)&SerialRead);
-
- return TIMEOUT;
- }
-
- BOOL InitModem(void)
- {
- STRPTR ptr;
- UWORD c;
- BOOL validEscape;
-
- #define MAX_AT_RETRIES (3)
-
- /* try to get the modem's attention. */
- for (c = 0; c < MAX_AT_RETRIES; c++) {
- SerWrite("AT\r", 3);
- if (SerWaitString("OK\r\n", 6))
- break;
- }
-
- if (c == MAX_AT_RETRIES) {
- ErrorMsg("modem %ld not responding.", openedModem);
- ULog(ph, -1, "modem %ld not responding.", openedModem);
- return FALSE;
- }
-
- Delay(TICKS_PER_SECOND);
-
- ClearSerial();
-
- /* now start sending the init string out */
-
- ptr = openedMi->mi_ModemInit;
-
- while (c = *ptr++) {
- validEscape = FALSE;
-
- if (c == '\\') {
- validEscape = TRUE;
-
- switch (tolower(*ptr)) {
- case 'd':
- Delay(2 * TICKS_PER_SECOND);
- c = 0xFFFF;
- break;
-
- case 'r':
- c = '\r';
- break;
-
- default:
- validEscape = FALSE;
- break;
- }
- }
-
- if (c != 0xFFFF)
- SerPutChar(c);
-
- if (c == '\r')
- while ((c = SerGetRawChar(-100)) != TIMEOUT) ;
-
- if (validEscape) {
- ptr++;
- }
- }
-
- return TRUE;
- }
-