diff -c -r tmp/libmodem-1.0.0/Makefile libmodem-1.0.0/Makefile *** tmp/libmodem-1.0.0/Makefile Tue Aug 26 16:19:48 1997 --- libmodem-1.0.0/Makefile Sun Dec 21 07:51:15 1997 *************** *** 31,37 **** include CONFIG.MAKE ! CFLAGS= -I. $(CCFLAGS) $(DEFINES) $(DEBUG) -DLIBRARY -DLIB_VERSION=$(LIB_VERSION) MANFIN= $(MANDIR)/man$(MANEXT) # for the library --- 31,37 ---- include CONFIG.MAKE ! CFLAGS= -I. $(CCFLAGS) $(DEFINES) $(DEBUG) -DLIBRARY -DLIB_VERSION=$(LIB_VERSION) -DSMS_FIX MANFIN= $(MANDIR)/man$(MANEXT) # for the library diff -c -r tmp/libmodem-1.0.0/line_manage.c libmodem-1.0.0/line_manage.c *** tmp/libmodem-1.0.0/line_manage.c Tue Aug 26 08:48:22 1997 --- libmodem-1.0.0/line_manage.c Sun Dec 21 07:51:15 1997 *************** *** 638,643 **** --- 638,917 ---- return FAILURE; } + + #if defined(SMS_FIX) + /* Angelo: + * + * Problem with this routine: + * When we send command strings to the modem + * We are expecting return values from the modem in the form + * of simple strings. + * + * When we send the ATDT command we expect a CONNECT + * string to be returned, if we write the ATDT command and read + * the result into a buffer - reading 1000 charaters we get the + * result and potentially any other data that may follow. It is + * a very bad idea to throw away this data as an application + * will never see it!!! + * + * The solution is to read the result a character at a time + * stopping as soon as we get the resonse string we are looking + * for. + */ + + static + int talk_to_modem(int fd, struct modems *device, char *command, int isdial) { + fd_set readfds; + struct timeval tmout; + int ret; + int cmd_found = FAILURE; + int retries = SYNC_RTRY; + int mdm_read_retries = READ_RTRY; + char *cmdbuffer; + char *bigbuffer; + char *cmdmodem; + char *buffer; + + cmdbuffer = mdmalloc(BUFSIZE); + + if (!cmdbuffer) + return -EMDMEM; + + bigbuffer = mdmalloc(BUFSIZE); + + if (!bigbuffer) { + mdmfree(cmdbuffer); + return -EMDMEM; + } + + cmdmodem = mdmalloc(BUFSIZE); + + if (!cmdmodem) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + return -EMDMEM; + } + + buffer = mdmalloc(BUFSIZE); + + if (!buffer) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + return -EMDMEM; + } + + #if defined(DEBUG) + mdm_log(LOG_DEBUG, "Using SMS_FIX version of talk_to_modem\n"); + mdm_log(LOG_DEBUG, "writing >> %s << to modem\n", command); + #endif /* DEBUG */ + + /* + * write the command to modem + */ + + if (write(fd, command, strlen(command)) != strlen(command)) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMWRITE); + } + + mdm_log(LOG_INFO, "written >> %s << to modem\n", command); + + /* + * I need to check this thing. + */ + sleep (1); + + + /* Angelo: + * + * As we will be reading only 1 character at + * a time to avoid eating data, mdm_read_retries + * needs to be higher, the size of the buffer + * is ok forthis. + */ + + mdm_read_retries = BUFSIZE; + + while (!cmd_found) { + + memset(bigbuffer, 0, BUFSIZE); + + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + + tmout.tv_sec = device->dl; + tmout.tv_usec = 0; + + ret = select(FD_SETSIZE, &readfds, NULL, NULL, &tmout); + + if (ret < 0) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMSEL); + } + + if (!FD_ISSET(fd, &readfds)) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMNOFDSET); + } + + + /* Angelo: + * + * Data is waiting to be read from fd + * read only 1 character and append to buf. + * Reading more than 1 character will potentially + * eat into data being sent from remote machine + */ + + if ((ret = read(fd, bigbuffer, 1)) < 0) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMREAD); + } + + bigbuffer[ret] = '\0'; + + + #if defined(DEBUG) + mdm_log(LOG_DEBUG, "read >> %s << from modem\n", bigbuffer); + #endif /* DEBUG */ + + strcat(cmdbuffer, bigbuffer); + + if (get_command(cmdbuffer, cmdmodem) == FAILURE) { + if (!(mdm_read_retries--)) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMRDRT); + } + continue; + } + + /* + * Reset read retries: we have found something. + */ + + mdm_read_retries = BUFSIZE; + + if (!strcmp(command, cmdmodem)) { + /* + * local echo enabled!!! strip out the command from modem answer!!!! + * that is "command\r\nOK\r\n" or something like that + */ + if (get_command(cmdbuffer, cmdmodem) == FAILURE) { + if (!(mdm_read_retries--)) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMRDRT); + } + continue; + } + + mdm_read_retries = BUFSIZE; + } + + mdm_log(LOG_INFO, "checking >> %s << from modem\n", cmdmodem); + + if (check_for_string(cmdmodem, buffer) == SUCCESS) + cmd_found = 1; + if (!(retries--)) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMSYNC); + } + } + + /* + * If modem return ERROR, we must return the error now + * if it is RINGing we must return. + */ + if (!strcmp(buffer, "ERROR")) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMERROR); + } + + if (!strcmp(buffer, "RING")) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMRING); + } + + if (isdial) { + /* + * check the answer against 'CONNECT' or BUSY + */ + if (!strcmp(buffer, "CONNECT")) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -ENOMDMERR); + } + if (!strcmp(buffer, "BUSY")) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMBUSY); + } + if (!strcmp(buffer, "NO DIALTONE")) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMTONE); + } + if (!strcmp(buffer, "NO ANSWER")) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EMDMANSW); + } + } else { + /* + * check the answer against 'OK' ? No err : Unk err + */ + if (!strcmp(buffer, "OK")) { + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -ENOMDMERR); + } + } + mdmfree(cmdbuffer); + mdmfree(bigbuffer); + mdmfree(cmdmodem); + mdmfree(buffer); + return (mdmerrno = -EUNMDMERR); + } + + #else /* SMS_FIX */ + static int talk_to_modem(int fd, struct modems *device, char *command, int isdial) { fd_set readfds; *************** *** 872,877 **** --- 1146,1154 ---- mdmfree(buffer); return (mdmerrno = -EUNMDMERR); } + + #endif /* SMS_FIX */ + static int check_for_string(char *from, char *to) { int i;