SMPP получение статуса сообщения

Greezley

Новичок
Всем привет. Такая ситуация: делаю смс рассылку на сайте по протоколу SMPP. Для отправки использую SMPPclass c сайта http://www.phpclasses.org/package/1373-PHP-Sends-SMS-messages-via-an-SMPP-server.html

Мне нужно получать статус отправленных сообщений, использовал для этого query_sm. Но не сильно разобрался с синтаксисом PDU (возможно неправильно сформировал), и при отправке запроса сервер возвращает ошибку 255.
Если кто-то сталкивался с SMPP подскажите, пожалуйста, как правильно сформировать запрос на получение статуса сообщения?
 

zerkms

TDD infected
Команда форума
Greezley
255 - не определённая стандартом ошибка. В таких случаях лучше писать администратору SMSC (или кто там у тебя есть для связи) и спрашивать, почему ты получил в ответ такую невнятную ошибку.

ps: а вообще даже сам протокол smpp v3.4 говорит, что ошибки в query_sm_resp в большинстве случаев стандартом не определены и специфичны для сетей. Так что бей челом в саппорт.
pps: а не проще взять kannel и не мучиться с пхп?
 

Greezley

Новичок
Не знаю, с kannel не знаком, так что вряд ли проще)) На пхп практически реализовал, осталось только статус проверять. К сожалению, поддержка не слишком разговорчива, но попробую постучать...
Спасибо.
 

zerkms

TDD infected
Команда форума
Greezley
Все вопросы, которые у меня возникали по поводу ошибок, не описанных документацией всегда заканчивались поддержкой. Потому что как правило это network-specific ошибки, о которых ты со своей стороны почти наверняка догадаться не сможешь (например - пределы для delivery date, или вообще наличие этого поля в PDU). По крайней мере мне за полгода интенсивной работы и примерно 5 случаяв столкновения с неопределёнными ошибками найти зависимости и угадать причины ещё не получилось ни разу )))

По поводу kannel - почитай всё таки о нём, переделывать придётся мало (с учётом того, что у тебя слой работы с SMPP вынесен отдельно), а работает он 100% лучше твоего кода.
 

Greezley

Новичок
В общем поддержка сказала, что PDU не правильно сформировано, что им приходит только command_length, command_status, sequence_number, хотя я и другие поля запаковывал функцией pack(). Скорее всего не правильно, потому что я в этом кодировании не сильно разбираюсь. Я просто кидал вот-так:

$pdu = pack("a",$message_id.chr(0),$source_addr_ton.chr(0),$source_addr_npi.chr(0),$source_addr);

Но там по-идеи нужно формат указывать как-то по-другому. Если есть знающие люди подскажите, пожалуйста. Я не имею представления как оно должно быть сформировано с точки зрения этой функции..
 

Greezley

Новичок
Всё, вроде разобрался. Сформировал так:

$message_id = $message_id.chr(0);
$message_id_len = strlen($message_id);
$source_addr_ton = $source_addr_ton.chr(0);
$source_addr_npi = $source_addr_npi.chr(0);
$source_addr = $source_addr . chr(0);
$source_addr_len = strlen($source_addr);

$pdu = pack("a{$message_id_len}cca{$source_addr_len}",$message_id,$source_addr_ton,$source_addr_npi,$source_addr);

Ответ приходит без ошибки. Всё дело в том, что не знал как правильно упаковываются данные функцией pack().
Спасибо за помощь)
 

tyu

Новичок
Greezley, я использую тот же код отправки SMS что и ты. А вот с получением статуса сообщений голову уже сломал. Можешь дать полный код получения статуса?
 

Greezley

Новичок
Конечно. Могу даже весь класс скинуть. Только вот в чем беда, после общения с SMSC, оказалось что они не хотят хранить все сообщения у себя в базе, т.е. я не могу использовать query_sm, а после определения статуса сообщения отсылают мне сообщение delivery. Так что я получаю статусы через delivery. А моя реализация query_sm даже не знаю работает или нет, ибо протестировать не смог.
Надо поискать, где у меня что осталось и скину)
 

Greezley

Новичок
Вот функции для query_sm. Пытался реализовать в стиле автора, они схожи с sendSMS.
Вызывается функция StatusSMS, которой передаётся id сообщения, и должен быть установлен адрес (альфаимя) с которого отправлялось сообщение.
Разбор ответа центра думаю сам реализуешь.

PHP:
function StatusSMS($message_id)
	{
		if (!$this->_socket) {
			// not connected
			return;
		}
		$pdu = "";

		$message_id = $message_id;
		
		//default source TON and NPI for international sender
		$source_addr_ton = 1;
		$source_addr_npi = 1;
		$source_addr = $this->_source_address;
		if (preg_match('/\D/', $source_addr)) //alphanumeric sender
		{
			$source_addr_ton = 5;
			$source_addr_npi = 0;
		}
		elseif (strlen($source_addr) < 11) //national or shortcode sender
		{
			$source_addr_ton = 2;
			$source_addr_npi = 1;
		}	
		
		$status = $this->SendQuerySM($message_id,$source_addr_ton,$source_addr_npi,$source_addr);
		
		if ($status != 0) {
			$this->debug("SMPP server returned error $status.<br />");
		}
		
		return $status; 
		
	}

      function SendQuerySM($message_id,$source_addr_ton,$source_addr_npi,$source_addr){
		
		$message_id = $message_id.chr(0);
		$message_id_len  = strlen($message_id);
		$source_addr_ton = $source_addr_ton.chr(0);
		$source_addr_npi = $source_addr_npi.chr(0);
		$source_addr = $source_addr . chr(0);
		$source_addr_len = strlen($source_addr);					
		
		$pdu = pack("a{$message_id_len}cca{$source_addr_len}",$message_id,$source_addr_ton,$source_addr_npi,$source_addr);		
		$status = $this->SendPDU(CM_QUERY_SM, $pdu);
		return $status;
	
	}
 

dzin

Новичок
Добрый вечер, возможно вы можете послать весь класс и пример его использования.
 

Greezley

Новичок
Прикрепляю файл с классом,примером и документацией по СМПП.
До ума класс довести не удалось, он содержит много ненужных отладочных вещей и,может где-то, не самые правильные решения, но работать должен. Использование довольно тривиальное.
 

Вложения

  • 1,5 MB Просмотры: 94
Сверху