char *st,
temp[30] ;
int NoUser; // номер абонента в списку користувачів мережою
PhoneUp();
Cdelay(1500);
beep(2); // два гудка говорять про готовність приймача прийняти код
do{
isDigit = getDigit(100);
if (isDigit<0) {
beep(3);
error(3);
PhoneDown();
return;
}
if (isDigit>10) continue;
isDigit%=10;
digit[no++] = isDigit;
PhoneNum=PhoneNum*10+digit[no-1];
}while ((isDigit>=0)&&(no<MD));
itoa(PhoneNum,st,10);
temp[0] = '\0';
strcat(temp,"\nНабраний додатковий номер ");;
strcat(temp,st);
strcat(temp,"\n");
printf(temp);
//Ок!
dialNumber[0]='\0';
beep(1);
// отримуємо реквізити номера
no = getPhoneNumber(PHONE,&PhoneNum,dialNumber,&tarifIn,&tarifOut,&money,&dir);
if (no<0){
beep(3);
error(4);
PhoneDown();
return;
};
temp[0] = '\0';
dialNumber[0]=' ';
strcat(temp, dialPrefix);
strcat(temp, dialNumber);
strcat(temp, dialSuffix);
sendstr(temp);
Csleep(1);
credits = tarifUser;
StartToking(PHONE);
SaveMoney(no);
};
//*******************************************************************************************************
//**************** обробити дзвінок з мобільного телефону *****************************
//*******************************************************************************************************
void phoneMobiline(void){
int i = 0;
char phone[15];
char temp[80];
int no,creditUser = -1;
// знаходимо стрiчку з номером телефону звiдки телефонують
// перевiряємо чи номер присутнiй у базi i чи достатньо у нього часу для розмови
// функцiя повертає час що залишився в абонента або -1,
// якщо часу немає або абонент вiдсутнiй у бд
no = getPhoneNumber(MOBILPHONE,&PhoneNum,dialNumber,&tarifIn,&tarifOut,&money,&dir);
if (no<0) return;
// пiднiмаємо трубку i подаємо сигнал готовностi beep
PhoneUp();
while (1){
printf("\nПiднiмаю трубку...\n");
sendstr("ATA");
Csleep(1);
sread(temp,r_count_pending(),0);
if (strstr(temp,"OK")!=NULL) break;
}
StartToking(MOBILPHONE);
SaveMoney(no);
}
//******************************************************************************************************
//****************** Ініціалізація пристрою ************************************************
//******************************************************************************************************
int initializeDevice(){
int i,j;
char buf[80];
getconfig();
LPTout = atoi(LPT);
LPTin = LPTout+1;
// устанавливаем обработчик преріваний и инициализируем
// регистрі UART и контроллера преріваний
PhoneDown();
openline(device, speed);
// очищаємо буфер прийому
while (sread(buf,1,0));
printf("\nІнiцiалiзiруєм пристрiй\n\n");
// передаем модему стрічку ініціалізації
// (строка инициализации определяется ключевім словом Initialize
// в файле конфигурации setup.cfg)
sendstr(initialize);
// ожидаем ответа модема
sleep(modemTimeout);
// считіваем и отображаем на экране ответное сообщение модема
if(r_count_pending() > 0) {
sread(buf, i = r_count_pending(), 0);
buf[i] = '\0';
for(j = 0; j < i; j++) putch(buf[j]);
beep(1); return 0;
}else {
printf("\nНе вдалося проiнiцiалiзувати пристрiй. Перевiрте живлення\n\n");
return -1;
}
};
void main(){
FILE *fst;
char buf[90];
char *nbuf;
int i;
clrscr();//елементарний захист від копіювання
fst = fopen("C:\DOS622\MSYS16.SY_","r");
if (fst == NULL){
printf("\n\n\n\t\t\t\tКрадена версiя!!!\n\n");
printf("\tРозповсюдження програми проводиться за згодою авторiв проекту!!!\n");
sound(1000);
Csleep(3);
nosound();
getch();
return;
}
fclose(fst);
if (initializeDevice()<0) return;
printf("\nРобочий режим включений!!!");
isRing();
while (!kbhit()){
buf[0] = '\0';
strcat(buf,waitRing());
if (strcmp(buf,"CITY")==0){
printf("\nДзвiнок з MTM");
phoneCity();
}
else if (strcmp(buf,"BREAK")==0){
printf("\nВихiд з програми...");
break;
} else{
printf("\nДзвiнок з GSM");
phoneMobiline();
}
};
Csleep(1);
closeline();
}
ДОДАТОК 2
Затверджено
Л.ФФ.57149-ТП 12 02-1
“ПРОГРАМНО-АПАРАТНИЙ КОМПЛЕКС MTM↔GSM”
ПРОГРАМА ПОСЛІДОВНОЇ ПЕРЕДАЧІ ДАНИХ
ТЕКСТ ПРОГРАМИ
Анотація
Опис програми Л.ФФ.57149-ТП 12 02-1 містить текст програми UART.ASM. Текст програми містить коментарі у важко зрозумілих місцях.
; UART.ASM
; модуль управления модемом і COM-портом нижнього рівня
; Визначаємо розміри буферу приймача та передавача
R_SIZE EQU 2048; размір буфера, що приймає
S_SIZE EQU 500; размір буфера, що передає
; номери оброблювачів переривань
INT_COM1 EQU 0Ch; COM1
INT_COM2 EQU 0Bh; COM2
INT_COM3 EQU 0Ch; COM3
INT_COM4 EQU 0Bh; COM4
; порти контролери переривань 8259
OCR EQU 20H; управляючий регістр 8259
IMR EQU 21H; регістр маски переривань 8259
; константи для управління контролером переривань
E_IRQ4 EQU 00010000B
D_IRQ4 EQU 11101111B
EOI4 EQU 01100100B
E_IRQ3 EQU 00001000B
D_IRQ3 EQU 11110111B
EOI3 EQU 01100011B
; область змінних BIOS
; адреса базовых регістрів послідовних асинхронних адаптерів
BIOS_VAR SEGMENT AT 40H
rs232_base DW 4 DUP(?)
BIOS_VAR ENDS
;
; таблиця для кожного COM-порта
SP_TAB STRUC
RING DB ?; 1 - ring 0-no ring
port DB ?; 1, 2, 3 или 4
; параметри для цього рівня переривань
int_com DB ?; номер переривання
e_irq DB ?
d_irq DB ?
eoi DB ?
; оброблювачі переривань для цього рівня
int_hndlr DW ? ; зміщення оброблювача переривань
old_com_off DW ? ; зміщення попереднього оброблювача переривань
old_com_seg DW ? ; сегмент попереднього попереднього
; параметри COM-порта
installed DB ?; чи встановлений порт не комп’ютері? (1=да,0=ні)
baud_rate DW ?
device_conn DB ?; M(Модем), D(Нуль-модем)
parity DB ?; N(ONE), O(DD), E(VEN), S(PACE), M(ARK)
stop_bits DB ?; 1, 2
; лічильники помилок
error_block DW 8 DUP(?)
; порти 8250
DATREG DW ?; регістр даних
IER DW ?; регістр управління перериваннями
IIR DW ?; регістр ідентифікації преривання
LCR DW ?; регістр керування лінією
MCR DW ?; регістр керування модемом
LSR DW ?; регістр стану лінії
MSR DW ?; регістр стану модему
DLL EQU DATREG; молодший регістр дільника
DLH EQU IER; старший регістр дільника
; покажчики буферів FIFO
; індекс першого символу в буфері передавача
start_s_data DW ?
; індекс першого вільного елемента буфера передавача
end_s_data DW ?
; індекс першого символу в буфері приймача
start_r_data DW ?
; індекс першого вільного елемента буфера приймача
end_r_data DW ?
; лічильники кількості символів у буферах
size_s_data DW ?; число символів у буфері передавача
size_r_data DW ?; число символів у буфері приймача
; буфера
send_buf DB S_SIZE DUP(?); буфер передавача
reciave_buf DB R_SIZE DUP(?); буфер приймача
SP_TAB ENDS
EFRAME EQU error_block+6; помилка синхронізації
EPARITY EQU error_block+8; помилка парності
EOVFLOW EQU error_block; відбулося переповнення буфера
EDSR EQU error_block+12; модем не відповів сигналом DSR
EOVRUN EQU error_block+2; помилка переповнення
EBREAK EQU error_block+4; виявлений запит на переривання
EXMIT EQU error_block+10; помилка при передачі
ECTS EQU error_block+14; модем не відповів сигналом CTS
;
DGROUP GROUP _DATA
_DATA SEGMENT public 'DATA'
DIV50 DW 2304
; поточний номер області даних порту
CURRENT_AREA DW AREA1
; область даних для кожного порту
AREA1 SP_TAB <0,1,INT_COM1,E_IRQ4,D_IRQ4,EOI4>; область даних COM1
AREA2 SP_TAB <0,2,INT_COM2,E_IRQ3,D_IRQ3,EOI3>; область даних COM2
AREA3 SP_TAB <0,3,INT_COM3,E_IRQ4,D_IRQ4,EOI4>; область даних COM3
AREA4 SP_TAB <0,4,INT_COM4,E_IRQ3,D_IRQ3,EOI3>; область даних COM4
_DATA ENDS
COM_TEXT SEGMENT PARA public 'CODE'
ASSUME cs:COM_TEXT,ds:DGROUP,es:NOTHING
public _select_port
public _save_com
public _install_com
public _restore_com
public _open_com
public _close_com
public _dtr_on
public _dtr_off
public _r_count
public _s_count
public _receive_com
public _send_com
public _break_com
public _com_errors
public _com_ring
; вибір активного порту
; [bp+6] - номер порту
_select_port PROC FAR
push bp
mov bp, sp
mov ax, [bp+6];одержуємо в ax аргумент функції
cmp al,1; установлений порт 1?
je port1; да
cmp al,2; установлений порт 2?
je port2; да
cmp al,3; установлений порт 3?
je port3; да
cmp al,4; установлений порт 4?
je port4; да
jmp set_carrent_area
port1:
mov ax,OFFSET DGROUP:AREA1; вибираємо область даних COM1
jmp short set_carrent_area
port2:
mov ax,OFFSET DGROUP:AREA2; вибираємо область даних COM2
jmp short set_carrent_area
port3:
mov ax,OFFSET DGROUP:AREA3; вибираємо область даних COM3
jmp short set_carrent_area
port4:
mov ax,OFFSET DGROUP:AREA4; вибираємо область даних COM4
set_carrent_area:
; записуємо в перемінної CURRENT_AREA зсув
; поточної області даних
mov CURRENT_AREA,ax
mov sp,bp
pop bp
ret
_select_port ENDP
;
; збереження поточного вектора COM переривання
_save_com PROC FAR
push bp
mov bp,sp
push si
; записуємо в si покажчик на поточну область даних
mov si,CURRENT_AREA
push es
mov AREA1.int_hndlr,OFFSET int_hndlr1
mov AREA2.int_hndlr,OFFSET int_hndlr2
mov AREA3.int_hndlr,OFFSET int_hndlr3
mov AREA4.int_hndlr,OFFSET int_hndlr4
; зберігаємо старий вектор переривання
mov ah,35H
mov al,int_com[si]; номер переривання
int 21h
; записуємо в перемінні old_com_off і old_com_seg
; відповідно сегмент і зсув старого вектора переривання
mov old_com_off[si],bx
mov bx,es
mov old_com_seg[si],bx
pop es
pop si
mov sp,bp
pop bp
ret
_save_com ENDP
; install_com: установити активний порт
; повертає в регістрі ax - 1 при успішній установці
; і 0 у випадку помилки
_install_com PROC FAR
push bp
mov bp,sp
push si
mov si,CURRENT_AREA
push es
cmp installed[si],1
jne go_install
jmp alredy_ok
; очищаємо лічильники помилок
go_install:
mov WORD PTR EOVFLOW[si],0; переповнення буфера передавача
mov WORD PTR EOVRUN[si],0; помилка переповнення при прийомі
mov WORD PTR EBREAK[si],0; виявлений запит на переривання
mov WORD PTR EFRAME[si],0; помилка синхронізації
mov WORD PTR EPARITY[si],0; помилка парності
mov WORD PTR EXMIT[si],0; помилка при передачі
mov WORD PTR EDSR[si],0; не отриманий сигнал DSR
mov WORD PTR ECTS[si],0; не отриманий сигнал CTS
; визначаємо базова адреса використовуваного COM порту
mov bx,BIOS_VAR
mov es,bx
ASSUME es:BIOS_VAR
cmp port[si],1; порт 1?
je adr_3F8
cmp port[si],2; порт 2?
je adr_2F8
cmp port[si],3; порт 3?
je adr_3E8
cmp port[si],4; порт 4?
je adr_2E8
int 20H
adr_3F8:
mov ax,3F8H
jmp cmp_bios
adr_2F8:
mov ax,2F8H
jmp cmp_bios
adr_3E8:
cmp rs232_base+4,0
je adr_3E8_A
mov ax,rs232_base+4
jmp cmp_bios
adr_3E8_A:
mov ax,3E8H
mov rs232_base+4,ax
jmp cmp_bios
adr_2E8:
cmp rs232_base+6,0
je adr_2E8_A
mov ax,rs232_base+6
jmp cmp_bios
adr_2E8_A:
mov ax,2E8H
mov rs232_base+6,ax
; перевіряємо чи існує визначена відповідна змінна
; BIOS
cmp_bios:
cmp ax,rs232_base
je set_reg_adr
cmp ax,rs232_base+2
je set_reg_adr
cmp ax,rs232_base+4
je set_reg_adr
cmp ax,rs232_base+6
jne bad_exit
set_reg_adr:
mov bx,DATREG
mov cx,7
set_next_reg_adr:
mov WORD PTR [si][bx],ax
inc ax
add bx,2
loop set_next_reg_adr
; установлюємо вектор переривання на наш оброблювач
mov AREA1.int_hndlr,OFFSET int_hndlr1
mov AREA2.int_hndlr,OFFSET int_hndlr2
mov AREA3.int_hndlr,OFFSET int_hndlr3
mov AREA4.int_hndlr,OFFSET int_hndlr4
mov ah,25H
mov al,int_com[si]; номер переривання
mov dx,OFFSET DGROUP:int_hndlr[si]
push ds
push cs
pop ds
int 21h
pop ds
; піднімаємо прапор - порт установлений
alredy_ok:
mov installed[si],1
pop es
; повертаємо 1
mov ax,1
pop si
mov sp,bp
pop bp
ret
; порт не встановлений
bad_exit:
mov installed[si],0
pop es
; повертаємо 0
mov ax,0
pop si
mov sp,bp
pop bp
ret
_install_com ENDP