Send a short message via the serial port

xiaoxiao2021-03-06  22

Q Use serial port to connect the GSM phone to send and receive short messages, how to program the implementation in the application? Q We intend to develop a GPS system based on GSM short message mode, how to use SMS to communicate? A First, we have to know what the SMS specification developed by Esti. The specification related to the short message transceiver we discussed mainly includes GSM 03.38, GSM 03.40 and GSM 07.05. The front two focused on the technical implementation of SMS (including encoding mode), which specifies the SMS DTE-DCE interface standard (AT command set). There are three ways to send and receive SMS information: Block Mode, Text Mode, and PDU Mode. Block Mode is already a former yellow flowers, and it is rarely used. Text Mode is a plain text method that can be used in different character sets, which can also be used to send Chinese short messages, but domestic mobile phones are basically not supported, mainly for Europe and America. PDU MODE is supported by all mobile phones, you can use any character set, which is also a default encoding method. Text Mode is relatively simple, and we don't discuss it without custom data transmission. The content described below is the implementation method of sending and receiving a short message under PDU MODE. The PDU string is a string ASCII code, consisting of '0' - '9', 'A' - 'f' These numbers and letters. They are 8-bit bytes of hexadecimal number, or the BCD code decimal. The PDU string not only contains the displayable message itself, but also contains many other information, such as the SMS service center number, the target number, the reply number, the encoding method, and the service time. Transmit and receive PDU strings, the structure is not identical. We first use two actual examples to explain the structure and arrangement of the PDU string. Example 1 Send: SMSC number is 8613800250500, the other party number is 13851872468, the message content is "Hello!". PDU string from mobile phone can be 08 91 68 31 08 20 05 05 F0 11 00 0D 91 68 31 58 81 27 64 F8 00 00 00 06 C8 32 9B FD 0E 01 control specifications, specific analysis:

Segmentation Meaning Description 08SMSC address information Total 8 eight-bit bytes (including 91) 91SMSC address format (TON / NPI) with international format numbers (in front add ' ') 68 31 08 205 05 F0SMSC address 8613800250500, Supplement 'f' even 11 basic parameters (TP-MTI / VFP) send, TP-VP with relative format 00 message reference value (TP-MR) 00D target address number number total 13 decimal numbers (excluding 91 And 'F') 91 Target Address Format (TON / NPI) with International Format Number (Add ' ') 68 31 58 81 27 64 F8 Target Address (TP-DA) 8613851872468, 补 'f' even multiple numbers 00 Protocol Identification (TP-PID) is a normal GSM type, point-to-point mode 00 User information encoding mode (TP-DCS) 7-bit coding 00 validity period (TP-VP) 5 minutes 06 User information length (TP-UDL) actual Length 6 bytes C8 32 9B FD 0e 01 User Information (TP-UD) "Hello!" 2 Receive: SMSC number is 8613800250500, the other party number is 13851872468, the message content is "Hello!". The PDU string received by the mobile phone can be 08 91 68 31 08 20 05 05 F0 84 0D 91 68 31 58 81 27 64 F8 00 08 30 30 21 80 63 54 80 06 4F 60 59 7D 00 21 Control specifications, specific analysis:

Segmentation Meaning Description 08 The length of the address information is an eight-bit byte (including 91) 91SMSC address format (TON / NPI) with an international format number (in front add ' ') 68 31 08 205 05 F0SMSC address 8613800250500, supplement F 'makes even 84 basic parameters (TP-MTI / MMS / RP) reception, no more messages, there is a number of reply addresses 0D Reply Address number total 13 decimal numbers (excluding 91 and' f ') 91 reply Address Format (TON / NPI) with international format number (in front add ' ') 68 31 58 81 27 64 F8 Reply Address (TP-RA) 8613851872468, 补 'f' makes an even number 00 protocol identifier (TP-PID ) Is a normal GSM type, point-to-point mode 08 User information encoding mode (TP-DCS) UCS2 encoding 30 30 21 80 63 54 80 Time stamp (TP-SCTS) 2003-3-12 08:36:45 8 time zone 06 User Information Length (TP-UDL) actual length 6 byte 4f 60 59 7d 00 21 User Information (TP-UD) "Hello!" If the highest bit (TP-RP) of the basic parameter is 0, no reply address Three segments. Short messages issued from the Internet are often this situation. Note that the representation of the number and time is not compared to the normal order, and the odd number will be added to the odd number with 'F'. Q The above two have appeared 7-bit and UCS2 encodings, please tell us about these coding methods. A In PDU MODE, three coding methods can be used to encode the seminated content, which is 7-bit, 8-bit, and UCS2 encoding. 7-bit encoding is used to send a normal ASCII character, which encodes a string of 7-bit characters (highest bit 0) into 8-bit data, "compressed" into 7 per 8 characters; 8-bit The encoding is typically used to send data messages, such as pictures and ringtone, etc .; and UCS2 encodes to send Unicode characters. The maximum capacity of the user information (TP-UD) section of the PDU string is 140 bytes, so in these three coding modes, the maximum number of characters that can be sent is 160, 140, and 70, respectively. Here, all English letters, one Chinese character and a data byte are viewed as a character. It should be noted that the user information length (TP-UDL) of the PDU string is different in various coding methods. 7-bit encoding, refers to the number of characters of the original short message, not the number of bytes encoded. 8-bit encoding is the number of bytes. When UCS2 encodes, it is also the number of bytes, equal to twice the number of characters of the original short message. If there is a header (TP-UD) exists (TP-UDHI 1) in the TP-UD), in all encoding mode, the user information length (TP-UDL) is equal to the sum of the head length and the number of bytes encoded. If the compression algorithm suggested with GSM 03.42 (the TP-DCS is 3 bit is 001), the length is also the sum of the number of bytes or head length and the compression encoding after compression encoding. The 7-bit encoding process will be described below with a specific example. We encode English SMS "Hello!": Divide the source string into a group (less than 8 in this example), compressed between the complications, but there is no connection between each group. . The algorithm for achieving 7-bit encoding and decoding with C is as follows: // 7-bit encoding // psrc: Source string pointer

// PDST: Target Code String Pointer

// nsrclength: Source string length

// Return: Target Code String Length

INT GSMENCODE7BIT (Const Char * PSRC, Unsigned Char * PDST, INT NSRCLENGTH)

{

INT nsrc; // Source string count value

INT NDST; / / Target Code String Counting Value

INT nchar; // The number of characters in the group currently processed, the range is 0-7

Unsigned char nLEFT; / / Previous-byte residual data / / count value initialization

NSRC = 0;

NDST = 0;

// Distribute the source string into a group, compress into 7 bytes

// Cycle this processing process until the source string is processed

// If the group is less than 8 bytes, it can also be handled correctly.

While (NSRC

{

// Take the minimum 3 digits of the count value of the source string

Nchar = NSRC & 7;

/ / Treat a source of each byte of the source string

IF (nchar == 0)

{

/ / The first byte in the group is only saved, and when you are processed

NLEFT = * psrc;

}

Else

{

/ / Other bytes in the group, add the right part to the residual data to get a target coding byte

* PDST = (* psrc << (8-nchar)) | NLEFT;

// Save the left part of the byte, saved as a residual data

NLEFT = * psrc >> nchar;

/ / Modify the pointer and count value PDST of the target string;

NDST ;

}

/ / Modify the pointer and count value of the source string

PSRC ; NSRC ;

}

/ / Return to the length of the target string

Return ndst;

}

// 7-bit decoding

// psrc: source code string pointer

// PDST: Target string pointer

// nsrclength: Source Code String Length

// Return: Target String Length

INT GSMDECode7bit (Const unsigned char * psrc, char * pdst, int nsrclength)

{

INT nsrc; // Source string count value

INT NDST; / / Target decoding string count value

INT NBYTE; / / The number of bytes currently being processed, the range is 0-6

Unsigned char nLEFT; // Previous byte residual data

/ / Count value initialization

NSRC = 0;

NDST = 0;

// Group byte serial number and residual data initialization

NBYTE = 0;

NLEFT = 0;

// Divide the source data into a group, unzip into 8 bytes

// Cycle the process, until the source data is processed

// If you are less than 7 bytes, you can also process correctly

While (NSRC

{

// Add the right part of the source by add to the residual data, remove the highest bit, get a target decoder byte

* PDST = (* psrc << nbyte) | NLEFT) & 0x7f;

// Save the left part of the byte, saved as a residual data

NLEFT = * psrc >> (7-nbyte);

/ / Modify the pointer and count value of the target string

PDST ;

NDST ;

// Modify byte count value

NBYTE ;

/ / The last byte of a group

IF (nbyte == 7)

{

// Additional target decoder bytes

* PDST = NLEFT;

/ / Modify the pointer and count value of the target string

PDST ;

NDST ;

// Group byte serial number and residual data initialization

NBYTE = 0;

NLEFT = 0;

}

/ / Modify the pointer and count value of the source string

PSRC ;

NSRC ;

}

* PDST = 0;

/ / Return to the length of the target string

Return ndst;

}

It should be pointed out that the 7-bit set of character sets is incomplete to the ANSI standard character set, and some printable characters are also arranged below 0x20, but the English letters, Arabic numbers, and common symbols are the same. Use the algorithm described above to send and receive pure English short messages, the general situation should be enough. If it is French, German, Spanish, etc., contain "å", "é" characters, then press the output to check the table above, see the provisions of GSM 03.38. 8-bit encoding actually does not specify what specific algorithm does not need to be introduced. UCS2 encoding is a 16-bit Unicode wide character that converts each character (1-2 bytes) according to ISO / IEC 10646. In the Windows system, especially in 2000 / XP, the API function can be simply invoked to implement coding and decoding. If there is no system support, for example, the mobile module is controlled by the microcontroller to send and receive short messages. In the Windows environment, the algorithms that implemented UCS2 encoding and decoding with C are as follows: // UCS2 encoded // psrc: Source string pointer

// PDST: Target Code String Pointer

// nsrclength: Source string length

// Return: Target Code String Length

INT GSMENCODEUCS2 (Const Char * PSRC, Unsigned Char * PDST, INT NSRCLENGTH)

{

Int ndstlength; // unicode wide character number

Wchar wchar [128]; // unicode buffer

// String -> Unicode string

NDSTLENGTH = :: MultibyTetowideChar (CP_ACP, 0, PSRC, NSRCLENGTH, WCHAR, 128);

// High and low bytes, output

For (INT I = 0; i

{

// output a high byte

* PDST = wchar [i] >> 8;

// output low byte

* PDST = Wchar [i] & 0xff;

}

/ / Return to the length of the target coding string

Return ndstlength * 2;

}

// UCS2 decoding

// psrc: source code string pointer

// PDST: Target string pointer

// nsrclength: Source Code String Length

// Return: Target String Length

INT GSMDECodeucs2 (Const unsigned char * psrc, char * pdst, int nsrclength)

{

Int ndstlength; // unicode wide character number

Wchar wchar [128]; // unicode buffer

// High and low byte calls, meicode

For (int i = 0; i

{

// Pre-high byte

Wchar [i] = * psrc << 8;

// Lower low byte

Wchar [i] | = * psrc ;

}

// unicode string -> string

NDSTLENGTH = :: widechartomultibyte (CP_ACP, 0, Wchar, NSRCLENGTH / 2, PDST, 160, NULL, NULL);

// Output string adds an end conference

PDST [NDSTLENGTH] = '/ 0';

/ / Return to the target string length

Return ndstlength;

}

With the above encoding and decoding modules, the short message string cannot be encoded as the format required by the PDU string, and cannot directly decode the user information in the PDU string as a short message string, because it is still a string and word The segment of the data between the data is converted. This transformation can be recirculated to call SSCANF and SPRINTF functions. The algorithms that do not need these functions are provided, and they also apply to single-chip, DSP programming environments. // Printing string to convert to byte data // such as "C8329BFD0E01" -> {0xc8, 0x32, 0x9b, 0xfd, 0x0e, 0x01}

// psrc: Source string pointer

// PDST: Target Data Pointer

// nsrclength: Source string length

// Return: Target Data Length

INT GSMString2bytes (const char * psrc, unsigned char * pdst, int nsrclength)

{

For (int i = 0; i

{

/ / Output high 4 digits

IF (* psrc> = '0' && * psrc <= '9')

{

* PDST = (* psrc - '0') << 4;

}

Else

{

* PDST = (* psrc - 'a' 10) << 4;

}

PSRC ;

// output low 4 digits

IF (* psrc> = '0' && * psrc <= '9')

{

* PDST | = * PSRC - '0';

}

Else

{

* PDST | = * PSRC - 'a' 10;

}

PSRC ;

PDST ;

}

/ / Return to the target data length

ReturnNSRCLENGTH / 2;

}

// byte data transition to a printable string

// {0xc8, 0x32, 0x9b, 0xfd, 0x0e, 0x01} -> "c8329bfd0e01"

// psrc: source data pointer

// PDST: Target string pointer

// nsrclength: source data length

// Return: Target String Length

INT GSMBYTES2STRING (Const unsigned char * psrc, char * pdst, int nsrclength)

{

Const char Tab [] = "0123456789abcdef"; // 0x0-0xf character lookup table

For (int i = 0; I

{

// output low 4 digits

* PDST = Tab [* psrc >> 4];

/ / Output high 4 digits

* PDST = Tab [* psrc & 0x0f];

PSRC ;

}

// Output string adds an end conference

* PDST = '/ 0';

/ / Return to the target string length

Return nsrclength * 2;

} The core coding method of Q PDU has been clear. How do I implement short messages with the AT command? A In the above, we have discussed the encoding mode of the 7-bit, 8bit, and ucs2, and give the code. Now, focus on the PDU stroner coding and decoding process, and the AT command implementation method for GSM 07.05. These are the core code of the underlying, in order to ensure the portability of the code, we don't have to use the MFC class as much as possible, use ANSI C standard library functions. First, define the following constants and structures: // User information encoding mode #define GSM_7bit 0

#define GSM_8bit 4

#define GSM_UCS2 8

// Short message parameter structure, encoding / decoding shared

// where the string ends in 0

Typedef struct {

Char SCA [16]; // Short Message Service Center Number (SMSC Address)

CHAR TPA [16]; // Target number or reply number (TP-DA or TP-RA)

Char TP_PID; // User Information Protocol Identifier (TP-PID)

CHAR TP_DCS; // User Information Coding Method (TP-DCS)

Char tp_scts [16]; // Service time stamp string (TP_SCTS), used in reception

CHAR TP_UD [161]; / / Original user information (TP-UD before code or decoding)

CHAR INDEX; // Short message number, used in reading

} SM_PARAM;

Everyone has noticed the number and time in the PDU string, both two-two strings. The following two functions can be positive and reverse transform: // The normal sequence string is converted to two two-reversed strings. If the length is odd, then add 'F' to even

// such as "8613851872468" -> "683158812764f8"

// psrc: Source string pointer

// PDST: Target string pointer

// nsrclength: Source string length

// Return: Target String Length

INT GSMINVERTNUMBERS (Const Char * PSRC, Char * PDST, INT NSRCLENGTH)

{

INT NDSTLENGTH; / / Target String Length

Char ch; // Used to save a character

// Copy string length

Ndstlength = nsrclength;

// Two two times

For (int i = 0; i

{

CH = * psrc ; // Save the first character appearing first

* PDST = * psrc ; // The character appeared after copying

* PDST = ch; // Copy the character appeared first

}

// Source string length is odd?

IF (Nsrclength & 1)

{

* (PDST-2) = 'f'; // 补 'f'

NDSTLENGTH ; // Target string length plus 1

}

// Output string adds an end conference

* PDST = '/ 0';

/ / Return to the target string length

Return ndstlength;

}

// Two-two strings are converted to a normal sequential string

// 如: "683158812764f8" -> "8613851872468"

// psrc: Source string pointer

// PDST: Target string pointer

// nsrclength: Source string length

// Return: Target String Length

INT GSMSERIALIZENUMBERS (Const Char * PSRC, Char * PDST, INT NSRCLENGTH)

{

INT NDSTLENGTH; / / Target String Length

Char ch; // Used to save a character

// Copy string length

Ndstlength = nsrclength;

// Two two times

For (int i = 0; i

{

CH = * psrc ; // Save the first character appearing first

* PDST = * psrc ; // The character appeared after copying

* PDST = ch; // Copy the character appeared first

}

// The last character is 'f'?

IF (* (PDST-1) == 'f')

{

PDST -;

ndstlength -; // Target string length minus 1

}

// Output string adds an end conference

* PDST = '/ 0';

/ / Return to the target string length

Return ndstlength;

}

The following is a full string of PDUs. To simplify programming, some fields use a fixed value. // PDU encoding, used to prepare, send short messages

// psrc: Source PDU parameter pointer

// PDST: Target PDU string pointer

// Return: Target PDU Strings Length

INT GSMENCODEPDU (Const Sm_Param * Psrc, Char * PDST)

{

INT NLENGTH; / / String length

INT NDSTLENGTH; / / Target PDU String Length

Unsigned char buf [256]; // internal buffer

// SMSC address information

NLENGTH = Strlen (PSRC-> SCA); // SMSC address string length

BUF [0] = (char) (NLENGTH & 1) == 0? Nlength: NLENGTH 1) / 2 1; // SMSC address information length

BUF [1] = 0x91; // Fixed: with international format numbers

NdstLength = GSMBytes2String (buf, pdst, 2); // Convert 2 bytes to the target PDU string

NDSTLENGTH = GSMINVERTNUMBERS (PSRC-> SCA, & PDST [NDSTLENGTH], NLENGTH); // Convert SMSC to Target PDU Strings

// TPDU segment basic parameters, target address, etc.

NLENGTH = STRLEN (PSRC-> TPA); // TP-DA address string length

BUF [0] = 0x11; // Yes Send SMS (TP-MTI = 01), TP-VP with relative format (TP-VPF = 10)

BUF [1] = 0; // TP-MR = 0

BUF [2] = (char) NLENGTH; / / Target Address Digital Number (TP-DA Address String Real length)

BUF [3] = 0x91; // Fixed: with international format numbers

NDSTLENGTH = GSMBYTES2STRING (BUF, & PDSTLENGTH], 4); // Convert 4 bytes to the target PDU string

NDSTLENGTH = GSMINVERTNUMBERS (PSRC-> TPA, & PDST [NDSTLENGTH], NLENGTH); // Convert TP-DA to the target PDU string // TPDU segment protocol identification, coding method, user information, etc.

NLENGTH = Strlen (PSRC-> TP_UD); // The length of the user information string

BUF [0] = PSRC-> TP_PID; // Protocol Identification (TP-PID)

BUF [1] = PSRC-> TP_DCS; // User Information Coding Method (TP-DCS)

BUF [2] = 0; // Validity (TP-VP) is 5 minutes

IF (psrc-> tp_dcs == GSM_7bit)

{

// 7-bit encoding method

BUF [3] = NLENGTH; / / The length of the coding

NLENGTH = GSMENCODE7BIT (PSRC-> TP_UD, & BUF [4], NLENGTH 1) 4; // Convert TP-DA to Target PDU Strings

}

ELSE IF (psrc-> tp_dcs == GSM_UCS2)

{

// UCS2 encoding method

BUF [3] = GSMENCODEUCS2 (PSRC-> TP_UD, & BUF [4], NLENGTH); // Convert TP-DA to Target PDU Strings

NLENGTH = BUF [3] 4; // Nlength is equal to this segment data length

}

Else

{

// 8-bit encoding method

BUF [3] = Gsmencode8bit (PSRC-> TP_UD, & BUF [4], NLENGTH); // Convert TP-DA to the target PDU string

NLENGTH = BUF [3] 4; // Nlength is equal to this segment data length

}

NDSTLENGTH = GSMBYTES2STRING (BUF, & PDSTLENGTH], NLENGTH); // Convert this section data to the target PDU string

/ / Return to the target string length

Return ndstlength;

}

// PDU decoding for receiving, reading short messages

// psrc: Source PDU string pointer

// PDST: Target PDU parameter pointer

// Return: User Information String Length

INT gsmdecodepdu (const char * psrc, sm_param * pdst)

{

INT NDSTLENGTH; / / Target PDU String Length

Unsigned char TMP; // Interim byte variable

Unsigned char buf [256]; // internal buffer

// SMSC address information

GSMString2bytes (PSRC, & TMP, 2); // Take the length

TMP = (TMP - 1) * 2; // SMSC number string length

PSRC = 4; // Remove the pointer

GSMSerializenumBers (PSRC, PDST-> SCA, TMP); // Convert SMSC number to target PDU string

PSRC = TMP; / / Movement

// TPDU segment basic parameters, reply address, etc.

GSMSTRING2BYTES (PSRC, & TMP, 2); // Take basic parameters

PSRC = 2; // Remove the pointer

IF (TMP & 0x80)

{

/ / Contain the reply address, retrieve the address information

GSMSTRING2BYTES (PSRC, & TMP, 2); // Take the length IF (TMP & 1) TMP = 1; // Adjust the parity

PSRC = 4; // Remove the pointer

GSMSERIALIZENUMBERS (PSRC, PDST-> TPA, TMP); // Take the TP-RA number

PSRC = TMP; / / Movement

}

// TPDU segment protocol identification, encoding method, user information, etc.

GSMString2bytes (psrc, (unsigned char *) & pdst-> tp_pid, 2); // Take the protocol identifier (TP-PID)

PSRC = 2; // Remove the pointer

GSMString2bytes (PSRC, (unsigned char *) & pdst-> tp_dcs, 2); // Take the encoding method (TP-DCS)

PSRC = 2; // Remove the pointer

GSMSerializenumBers (PSRC, PDST-> TP_SCTS, 14); // Service Timestamp String (TP_SCTS)

PSRC = 14; // Remove the pointer

GSMSTRING2BYTES (PSRC, & TMP, 2); // User Information Length (TP-UDL)

PSRC = 2; // Remove the pointer

IF (PDST-> TP_DCS == GSM_7bit)

{

// 7-bit decoding

NDSTLENGTH = GSMSTRING2BYTES (PSRC, BUF, TMP & 7? (int) TMP * 7/4 2: (int) TMP * 7/4); // Format Conversion

GSMDecode7bit (buf, pdst-> tp_ud, ndstlength); // Convert to TP-DU

NDSTLENGTH = TMP;

}

Else IF (pdst-> tp_dcs == GSM_UCS2)

{

// UCS2 decoding

ndstlength = GSMString2bytes (PSRC, BUF, TMP * 2); // Format Conversion

NDSTLENGTH = GSMDECodeucs2 (BUF, PDST-> TP_UD, NDSTLENGTH); // Convert to TP-DU

}

Else

{

// 8-bit decoding

ndstlength = GSMString2bytes (PSRC, BUF, TMP * 2); // Format Conversion

NDSTLENGTH = GSMDECode8bit (buf, pdst-> tp_ud, ndstlength); // Convert to TP-DU

}

/ / Return to the target string length

Return ndstlength;

}

According to GSM 07.05, send a short message to use the AT CMGS command, read the short message with the at cmgr command, list short messages with the at cmgl command, delete the short message with the AT CMGD command. However, the AT cmgl command can read all short messages, so we use it to read the short message function without using AT CMGR. Here is the implementation code for sending, reading, and deleting short messages: // Send a short message

// psrc: Source PDU parameter pointer

Bool GsmsendMessage (const sm_param * psrc)

{

Int npduLength; // PDU string length

Unsigned char nsmsclength; // SMSC string length INT NLENGTH; / / The data length received by the serial port

Char cmd [16]; // Command string

CHAR PDU [512]; // PDU string

CHAR ANS [128]; // Answering

npduLength = Gsmencodepdu (PSRC, PDU); // According to PDU parameters, encoded PDU strings

STRCAT (PDU, "/ x01a"); // Ended Ctrl-Z

GSMString2bytes (PDU, & nsmsclength, 2); // Take the SMSC information length in the PDU string

NSMSCLENGTH ; // plus the length byte itself

// The length in the command does not include the length of the SMSC information, with a data byte count

Sprintf (CMD, "AT CMGS =% D / R", NPDulength / 2 - nsmsClength; // Generate Commands

WriteComm (CMD, Strlen (CMD)); // Pre-output command string

NLENGTH = Readcomm (ANS, 128); // Read answering data

/ / Determine if "/ R / N>" can be found

IF (NLENGTH == 4 && Strncmp (ANS, "/ R / N>", 4) == 0)

{

WriteComm (PDU, Strlen (PDU)); // Get affirmative answers, continue to output a PDU string

NLENGTH = Readcomm (ANS, 128); // Read answering data

/ / Determine the success of " CMS ERROR" according to Can I find it?

IF (NLENGTH> 0 && Strncmp (ANS, " CMS Error", 10)! = 0)

{

Return True;

}

}

Return False;

}

// Read short messages

// Use cmgl instead of cmgr, you can read all short messages in one time

// PMSG: Short message buffer must be large enough

// Return: Short message

INT GSMReadMessage (SM_PARAM * PMSG)

{

INT NLENGTH; / / The data length received by the serial port

INT NMSG; // short message count value

CHAR * PTR; / / internal data pointer

Char cmd [16]; // Command string

CHAR ANS [1024]; // Answering

NMSG = 0;

PTR = ANS;

Sprintf (CMD, "AT CMGL / R"); // Generate Commands

WriteComm (CMD, Strlen (CMD)); // Output Command Strings

NLENGTH = Readcomm (ANS, 1024); // Read answer data

/ / Determine the success of " CMS ERROR" according to Can I find it?

IF (NLENGTH> 0 && Strncmp (ANS, " CMS Error", 10)! = 0)

{

// Recycled each short message to " cmgl:"

While (PTR = strstr (PTR, " CMGL:"))! = null)

{

PTR = 6; // Skip " CMGL:" SSCANF (PTR, "% D", & PMSG-> index); // Read the serial number

Trace ("INDEX =% D / N", PMSG-> index);

PTR = strstr (PTR, "/ r / n"); // Look for a row

PTR = 2; // Skip "/ R / N"

GSmDecodePdu (PTR, PMSG); // PDU string

PMSG ; // Prepare to read a short message

NMSG ; // short message count plus 1

}

}

Return NMSG;

}

// Delete short messages

// Index: Short message number, starting from 1

Bool GsmdeeeteMessage (Const Int Index)

{

INT NLENGTH; / / The data length received by the serial port

Char cmd [16]; // Command string

CHAR ANS [128]; // Answering

Sprintf (CMD, "AT CMGD =% D / R", INDEX); // Generate Commands

/ / Output command string

WriteComm (CMD, Strlen (CMD));

// Read answer data

NLENGTH = Readcomm (ANS, 128);

/ / Determine the success of " CMS ERROR" according to Can I find it?

IF (NLENGTH> 0 && Strncmp (ANS, " CMS Error", 10)! = 0)

{

Return True;

}

Return False;

}

The WriteComm and READCOMM functions are used above the AT command, which is used to read and write the serial port, depending on the specific operating system. In the Windows environment, in addition to the MSCOMM control, and some ready-made serial communication classes, some Windows APIs can be simply invoked. The following is the main code implemented using the API, pay attention to the synchronization (blocking) mode of the timeout control. // Serial port equipment handle

Handle HCOMM;

// Open the serial port

// pport: serial port name or device path, available "COM1" or "//./com1", recommended the latter

// nbaudrate: baud rate

// nparity: parity

// NBYTESIZE: Data byte width

// nstopbits: Stop bit

Bool OpenComm (Const Char * Pport, Int Nbaudrate, Int NPARITY, INT NBYTESIZE, INT NSTOPBITS)

{

DCB DCB; // Serial Pull

CommTIMEOUTS TIMEOUTS = {// Serial port timeout control parameters

100, // Read characters interval timeout: 100 ms

1, // read the time of each character: 1 ms (n characters for N ms)

500, // Basic (extra) Read time: 500 ms

1, // Write the time of each character: 1 ms (n characters for N ms)

100}; // Basic (additional) Writing timeout: 100 ms

hcomm = cretefile (pport, // serial port name or device path

Generic_read | generic_write, // Read and write

0, // Sharing method: exclusive null, // default security descriptor

Open_existing, // creation method

0, // Do not set file properties

NULL); // Do not need to refer to the template file

IF (hcomm == invalid_handle_value) return false; // Open serial port failed

Getcommstate (hcomm, & dcb); // Take DCB

Dcb.baudrate = NBAUDRATE

DCB.BYTESIZE = NBYTESIZE;

DCB.PARITY = NPARITY;

DCB.Stopbits = NStopbits;

Setcommstate (HCOMM, & DCB); // Set DCB

SetupComm (hcomm, 4096, 1024); // Setting the input and output buffer size

Setcommtimeouts (hcomm, & timeouts); // Set timeout

Return True;

}

// Turn off the serial port

Bool closecomm ()

{

Return CloseHandle (HCOMM);

}

// write serial port

// PDATA: Data buffer pointer to be written

// Nlength: The data length to be written

Void WriteComm (void * pdata, int NLENGTH)

{

DWORD DWNUMWRITE; / / The data length issued by the serial port

Writefile (HCOMM, PDATA, (DWORD) NLENGTH, & DWNUMWRITE, NULL

}

// Read the serial port

// PDATA: The data buffer pointer to be read

// Nlength: The maximum data length to be read

// Return: Data length actually read

Int Readcomm (void * pdata, int NLENGTH)

{

DWORD DWNUMREAD; / / The data received by the serial port

Readfile (HCOMM, PDATA, (DWORD) NLENGTH, & DWNUMREAD, NULL

Return (int) DWNumRead;

}

转载请注明原文地址:https://www.9cbs.com/read-42964.html

New Post(0)