Auther: Guo wenxue data: 2008.11.20 Refer to the process of sending and receiving faxes from 3 types of fax machines: Http://hi.baidu.com/kkernel/blog/item/05ffd52e87e9b9574ec22663.html Reference source code analysis of mgetty-1.1.36: Phase Modem sending command: Ate0; At + fclass = 1; Atdt628; // Our fax extension number Modem return: =================================== Part1: modem echo ==================================== Rev 9: 0x61 0x74 0x64 0x74 0x36 0x32 0x38 0x0d 0x0a A t d t 6 2 8/R/n =================================== Part2: fax return "Connect" ============================= Rev 11: 0x0d 0x0a 0x43 0x4f 0x4e 0 4E 0x45 0x43 0x54 0x0d 0x0a /R/n C o n e c T/R/n =================================== Part3: NSF frame ============================== Rev 24: 0xff 0x03 0x20 0x00 0x00 0x56 0x55 0x55 0x00 0x8c 0x90 0x80 0x34 0x0c 0x94 0x37 0x10 0x03 0x0d 0x0a 0x4f 0x4b 0x0d 0x0a Dle etx/R/n o k/R/n Note: In the int fax1_dial_and_phase_ AB _ P2 (dial_cmd, FD), char * dial_cmd, int FD) function of class1.c: 0x03 à 0x10 is the NSF frame, which is marked by the 0x20 value. Code: If (LEN = faxinclureceive_frame (FD, first? , 30, framebuf) // read the modem and return it to framebuf. Switch (framebuf [1]) { Case t30_csi: fax?copy_id (framebuf); break; Case t30_nsf: fax?incoming_nsf (framebuf + 2, len-2); break; // if it is NSF Case t30_dis: fax?parse_dis (framebuf); break; // if it is dis, the following describes Case t30_dcn: fax?send_dcn (FD, 20); return error; Default: Lprintf (l_warn, "unexpected Frame Type 0x % 02x", framebuf [1]); } Fax1_incoming_nsf is defined in faxlib. C; Fax‑parse_dis is defined in class1lib. C; =================================== Part4: remote fax information ======================== Rev 16: 0xff 0x03 0x40 0x32 0x30 0x37 0x30 0x33 0x37 0x39 0x35 0x37 0x32 0x30 0x20 0x20 Etx @ 2 0 7 0 3 7 9 5 7 2 0 space // This is our fax number Rev 17: 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0xbd 0x64 0x10 0x03 0x0d 0x0a 0x4f 0x4b 0x0d 0x0a Space ---------------------------------> space DLE etx/R/n o k/R/n ========================= Part5: dis frame remote fax machine capability ========================= Rev 19: 0xff 0x13 0x80 0x00 0xEE 0xa8 0xc4 0x80 0x11 0xe7 0xb3 0x10 0x03 0x0d 0x0a 0x4f 0x4b 0x0d 0x0a Note: 0x80 indicates that this is dis frame. Refer to the above Code. In the void fax?parse_dis _ p1 (FRAME), uch * frame) function of class1lib. C: First, the frame is known as 0x00 (FIF). In this way, frame [1] = 0xEE frame [2] = 0xa8. The following analyzes the two bytes based on source code Annotations: 0xEE = 1110 1110 0xa8 = 1010 1000 Bit9 is offset starting from the position 0x00 (FIF), that is, bit0 of frame [1], and so on: Bit 9: 0-> fax_to_poll = false Bit 10: 1-> can receive // using ing capabilities Bit 11-14: 1110 1110 (0xEE) & 0011 1100 (0x3c) = 0x2c So: Case 0x2c: remote_cap.br = v17 | V29 | v27ter = FFE Bit 15: 1-> remote_cap.vr = 1; Bit 16: 1-> remote_cap.df = 1; Bit 17-18: remote_cap.wd = frame [2] & 0x03; Page width: valid: 0/1/2 = 215/255/303mm: 00-> 215mm Bit 19-20: remote_cap.ln = (frame [2]> 2) & 0x03; Page length: valid: 0/1/2 = A4/B4/unlimited: 10-> Unlimited Bit 21-23: remote_cap.st = fax1_st_table [(frame [2]> 4) & 0x07]. St; (Frame [2]> 4) & 0x07 = 0x0010 = 2 Table query: fax1_st_table [2]. St = {3, 10, 10, "10 ms"}/* 2 = 010 */ Struct fax1_st_table {int st; int ms_n; int ms_f; char * txt ;}; So remote_cap.st = 3. Bit 24: Extend bit If (frame [2] & 0x80)/* extend bit */The highest bit is 1, so it is true { /* Bit 27: ECM */ If (frame [3] & 0x04) // 0xc4 & 0x80 = 0 without ECM Remote_cap.ec = 1; } Phase B: The Int fax?send_dcs _ P2 (FD, s_time), int FD, int s_time) function of the file class1lib. C is used by the modem to send the DCS frame to remote Fax: While (dcs_btp-> speed> 2400 && (Dcs_btp-> speed> fax1_max | (dcs_btp-> flag & fax1_ftm & remote_cap.br) = 0 )) Dcs_btp ++; Where: Fax1_max is initialized to a maximum rate of 14400, that is, v17_14400; Fax?ftm is composed of At + FTM =? The speed supported by the command to get the modem. Our modem returns the following: 98,121,122,145,146, Therefore, the modem supports the full rate defined by struct fax?btable fax=btable [] In class1lib. C; Remote_cap.br is onPhaseRemote_cap.br = v17 | V29 | v27ter = FFE In this way, the negotiation rate between the local modem and remote fax should be v29_9600, that is, dcs_btp = fax1_btable [3]; In this case, the sent DCS frame is: Framebuf [0] = 0x03 | t30_final = 0x03 | 0x10 = 0x13; Framebuf [1] = fax1_dis | t30_dcs = 0x0 | 0x82 = 0x82; // fax?dump_frame () will set last bit to 0 Framebuf [2] = 0; Framebuf [3] = 0x02 | dcs_btp-> dcs_bits | (faxrjres & remote_cap.vr) <6) | 0x00 = 0x02 | 0x04 | (1 & 1) <6) | 00 = 0100 0010 = 0x46; Framebuf [4] = 0x00 // 00-> 215 width | 0x04 // B4 Length | 0x00 // scan time: 00->? | 0x00; // No extend bit = 0x04; |