>  기사  >  백엔드 개발  >  PHP는 직렬 포트를 통해 문자 메시지 보내기를 구현합니다.

PHP는 직렬 포트를 통해 문자 메시지 보내기를 구현합니다.

PHPz
PHPz원래의
2016-05-16 20:11:181092검색

기술의 발전에 따라 시간에 맞춰 SMS를 주고받는 분야에는 BLOCK 모드, AT 명령 기반 TEXT 모드, AT 명령 기반 PDU 모드의 세 가지 모드가 등장했습니다. 그중 TEXT MODE는 비교적 간단하며 많은 Nokia 휴대폰이 이 모드를 지원합니다. 대부분의 Siemens 휴대폰은 PDU 모드만 지원합니다. PDU 모드는 문자 메시지를 보내고 받는 방식입니다. 문자 메시지의 텍스트는 16진수 인코딩 후 전송됩니다. 현재 PDU가 BLOCK MODE를 대체했습니다.

SMS는 Etsi에서 개발한 사양입니다(GSM 03.40 및 GSM 03.38). 7비트 인코딩을 사용하면 최대 160자를 보낼 수 있지만 8비트 인코딩을 사용하면 최대 140자를 보낼 수 있습니다. 이는 일반적으로 휴대폰을 통해 직접 표시할 수 없으며 16비트 인코딩을 사용할 경우 최대 140자를 보낼 수 있습니다. 최대 70자, 대부분의 휴대폰에서 표시할 수 있는 유니코드(UCS2) 텍스트 정보를 표시하는 데 사용됩니다.

오늘 다룰 내용은 PDU MODE, UCS2 인코딩인데, 영어, 중국어 상관없이 최대 70자까지 전송할 수 있다는 뜻입니다.
"안녕하세요"라는 메시지를 보내고 싶다고 가정해 보겠습니다. 보내기 전에 휴대폰 SIM 카드가 있는 SMS 센터 번호를 알아야 합니다. 예를 들어 China Mobile의 SMS 센터 번호:

수신된 휴대폰 번호: 13638197275
항저우 SMS 센터 번호: 13800571500
SMS 내용: 안녕하세요
이 문자 메시지를 보내려면 인코딩 후 휴대전화에서 이를 실행합니다.
0891683180501705F011000D91683136187972F5000800044F60597D
이해가 안 되시면, 이 인코딩 문자열을 처음부터 끝까지 설명해 주세요. :
08 – SMS 센터 번호의 길이, 즉 (91) (683180501705F0)을 2로 나눈 길이, 즉 08 = (2)를 나타냅니다. 14) / 2
91 – SMS 센터 번호 유형을 나타냅니다. 91은 TON/NPI가 International/E.164 표준을 준수한다는 것을 의미합니다. 즉, 다른 값이 있기 전에 '' 기호를 추가해야 하지만 91이 가장 일반적으로 사용됩니다.
683180501705F0 - SMS 센터 번호. 약간의 위치 처리로 인해 실제 숫자는 8613800571500이 되어야 합니다(문자 F는 짝수 길이를 구성하기 위해 추가된 문자입니다).
11 - 파일 헤더 바이트
00 - 메시지 유형(TP-Message-Reference)
0D - 착신 번호 길이
91 - 착신 번호 유형

은 실제로 처리 중에, 우리는 일반적으로 프로그램에 11000D91을 하드 코딩합니다. 왜냐하면 중국에서는 이러한 데이터가 변경되지 않기 때문입니다.

683136187972F5 - 수신번호가 이동되었으며, 실제 전화번호는 "8613638197275" 입니다.

위 (00)(0D)(91)(683136187972F5)은 전체 문자 메시지의 대상 주소(TP-Destination-Address)의 두 번째 부분을 구성합니다.

계속...
00 - 프로토콜 식별 TP-PID, 일반적으로 00입니다
08 - 앞서 언급한 데이터 코딩 방식 TP-DCS(TP-Data-Coding-Scheme), 사용 USC2(16bit) 데이터 인코딩
00 - 유효기간 TP-VP(TP-Valid-Period)
04 - 길이 TP-UDL(TP-User-Data-Length), 정보 길이의 16배/ 2 04
4F60597D 문자 메시지 내용은 다음과 같습니다. 실제 내용은 "Hello"입니다.

위 상황을 기반으로 문자 메시지 인코딩을 위한 프로그램 스크립트를 작성할 수 있습니다.

1. SMS 센터 번호 처리:

1. SMS 센터 번호 "8613800571500"에서 번호를 제거하고 길이가 짝수인지 확인합니다. . 그렇지 않은 경우 마지막으로 F
=> “8613800571500F”
를 추가합니다. 2.
=> “683108501705F0″
3. SMS 센터 번호 앞에 91을 추가하면 국제화를 의미합니다.
=> “91683108501705F0″
4. 2. 2자리 16진수 문자열, 16 / 2 = 8 => “08″
=> “0891683108501705F0″

2. 휴대폰 번호 처리:

1. 휴대폰 번호 8613638197275를 삭제하고 길이가 짝수인지 확인하세요. 그렇지 않으면 끝에 F
=> 심지어 비트도 교환됩니다.
=> “683136187972F5″

3. 단문 메시지 처리:

1. 문자열을 유니코드 코드로 변환합니다. "Hello"는 4F60597D

2입니다. 길이를 2로 나누고 두 개의 16진수 숫자를 유지합니다. 즉, 4F60597D = 8/2 => "04",
=> 🎜>
4. 조합

1. 휴대폰 번호 앞에 문자열 11000D91을 추가합니다. (1100:고정, 0D: 휴대폰 번호 길이, + 기호를 제외한 16진수로 표현, 91:
을 휴대폰으로 전송) 91, 작은 Lingtong으로 보내는 것은 81),
은 11000D91 683136187972F5
=> 11000D91683136187972F5
2. 휴대폰 번호 뒤에 000800을 추가하고 문자 메시지 내용을 입력하세요.
11000D9 1683136187972F5 000800 044F60597D
=> 11000D91683136187972F5000800044F60597D
3. 전체 메시지 길이를 2로 나누어 10진수 2자리로 표시합니다. 🎜> 11000D91683136187972F5000800044F60597D = >38비트/2 => ; 19

5. 따라서 전송할 내용은

AT CMGF=0

최종 PHP 코드를 첨부합니다.

 9600, 
 'bits' => 8, 
 'stop' => 1, 
 'parity' => 0 
)); 
  
//$ff=dio_stat($fd); 
//print_r($ff); 
//echo "GSM AT is start on ttyS0\n"; 
  
//短信中心号码 
$smsc = "8613800571500"; 
$invert_smsc = invertNumbers($smsc); // 转换短信中心号码 
$inter = chr(13); // 回车字符 
  
$ctrlz = chr(26); // ctrl+z 
  
// 发送信息 
$text 
  = '你好'; 
$send_to = '8613638197275'; 
$pdu_phone = hex2str(utf82unicode($text)); 
$pdu_phone = sprintf("%02X", strlen($pdu_phone)/2) . $pdu_phone; 
$pdu_phone = '11000D91' . invertNumbers($send_to) . '000800' . $pdu_phone; 
$atcmd   = 'AT+CMGF=0' . $inter; 
@dio_write($fd, $atcmd); 
$atcmd   = 'AT+CMGS=' . sprintf("%d", strlen($pdu_phone)/2) . $inter; 
@dio_write($fd, $atcmd); 
$pdu_addr  = '0891' . invertNumbers($smsc); 
$pdu_all  = $pdu_addr . $pdu_phone . $ctrlz . $inter; 
@dio_write($fd, $pdu_all); 
dio_close($fd); 
  
// 我的是utf-8编码 
function utf82unicode($str)  
{ 
  return iconv("utf-8", "UCS-2BE", $str); 
} 
  
function hex2str($hexstring)  
{ 
  $str = ''; 
  for($i = 0, $len = strlen($hexstring); $i < $len; $i++) 
  { 
    $str .= sprintf("%02X", ord(substr($hexstring, $i, 1))); 
  } 
  return $str; 
} 
  
function invertNumbers($msisdn)  
{ 
  $len = strlen($msisdn); 
  if ( 0 != fmod($len, 2) ) 
  { 
    $msisdn .= "F"; 
    $len = $len + 1; 
  } 
  
  for ($i=0; $i
위 내용은 이 글의 전체 내용입니다. 모두 마음에 드셨으면 좋겠습니다.

더 많은 관련 튜토리얼을 보려면

초보부터 마스터까지 PHP 프로그래밍에 대한 전체 비디오 튜토리얼 세트
를 방문하세요.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.