| 
div.main {margin-left: 20pt; margin-right: 20pt} С.Кадаков 
       sgerr@clubpro.spb.ru 
      SMS-приложение. Часть 3.
      Отправка/прием сообщений.
       Мы продолжаем обсуждать команды протокола. Нам осталось 
      рассмотреть две самые интересные команды, с помощью которых, собственно, и 
      осуществляется прием/передача сообщений. Это команды submit_sm и 
      deliver_sm. Первая служит для отправки SMS от ESME в PLMN, а вторая 
      -- для приема SMS из PLMN.  
      submit_sm. command_id = 0x04
      Тело пакета submit_sm состоит из следующих полей: 
      
      
        
        
          Field name 
          Size (octets) 
          Type 
          Description 
         
          | service_type  | 
          Var. max 6 | 
          C-Octet String | 
          Используется для доступа к специальным функциям SMSC. Может 
            принимать значения: 
            
              ““ (NULL) Default 
              “CMT” Cellular Messaging 
              “CPT” Cellular Paging 
              “VMN” Voice Mail Notification 
              “VMA” Voice Mail Alerting 
              “WAP” Wireless Application Protocol 
              “USSD” Unstructured Supplementary Services Data 
             Если не используется (в большинстве случаев), выставляется в 
            NULL.   |  
        
          | source_address_ton  | 
          1 | 
          Integer | 
          Тип номера источника (см. пред. статью)  |  
        
          | source_address_npi  | 
          1 | 
          Integer | 
          Индикатор плана номеров источника (см. пред. статью)  |  
        
          | source_address  | 
          20 | 
          C-Octet String | 
          Адрес источника, если неизвестен выставляется в NULL  |  
        
          | dest_address_ton  | 
          1 | 
          Integer | 
          Тип номера получателя (см. пред. статью)  |  
        
          | dest_address_npi  | 
          1 | 
          Integer | 
          Индикатор плана номеров получателя (см. пред. статью)  |  
        
          | dest_address  | 
          20 | 
          C-Octet String | 
          Адрес получателя. Для mobile-terminated (т. е. предназначенных 
            для передачи непостредственно на сотовый телефон) сообщений это в 
            точности номер телефона.  |  
        
          | esm_class  | 
          1 | 
          Integer | 
          Указывает на тип сообщешия и его режим (mode). Может принимать 
            следующие значения: Bits 7 6 5 4 3 2 1 0 Meaning 
             Messaging Mode (bits 1-0) x x x x x x 0 0 Default 
            SMSC Mode (e.g. Store and Forward) x x x x x x 0 1 Datagram 
            mode x x x x x x 1 0 Forward (i.e. Transaction) mode x x x x x 
            x 1 1 Store and Forward mode (use to select Store and Forward mode 
            if Default SMSC Mode is non Store and Forward)
  Message 
            Type (bits 5-2) x x 0 0 0 0 x x Default message Type (i.e. 
            normal message) x x 0 0 1 0 x x Short Message contains ESME 
            Delivery Acknowledgement x x 0 1 0 0 x x Short Message contains 
            ESME Manual/User Acknowledgement
  GSM Network Specific 
            Features (bits 7-6) 0 0 x x x x x x No specific features 
            selected 0 1 x x x x x x UDHI Indicator (only relevant for MT 
            short messages) 1 0 x x x x x x Set Reply Path (only relevant for 
            GSM network) 1 1 x x x x x x Set UDHI and Reply Path (only 
            relevant for GSM network)
  При работе в т. н. Store and 
            Forward mode и отказе от использования дополнительных свойств (что 
            верно в большинстве случаев) это поле будет содержать 0.  |  
        
          | protocol_id  | 
          1 | 
          Integer | 
          Идентификатор протокола (специфично для сети). В стандарте GSM 
            этот параметр регулируется документом GSM 03.40 (т. н. "Библией 
            SMS") и используется для указания на низлежащий протокол связи ESME 
            с SMSC. В простейшем случае -- 0. |  
        
          | priority_flag  | 
          1 | 
          Integer | 
          При передаче по GSM сетям: 0 -- приоритет отсутствует, 1-3 -- 
            приоритет (равноправны). >3 -- не используется |  
        
          | schedule_delivery_time | 
          1 или 17 | 
          C-Octet String | 
          Время отложенного доведения (в формате SMPP -- см. ниже) или 0 
            для немедленного доведения. |  
        
          | validity_period | 
          1 или 17 | 
          C-Octet String | 
          Срок годности (в формате SMPP -- см. ниже) или 0 для срока 
            годности, установленного SMSC по умолчанию |  
        
          | registered_delivery  | 
          1 | 
          Integer | 
          Запрос на подтверждение доставки от SMSC (delivery_receipt). 1 
            -- требуется, 0 -- не требуется  |  
        
          | replace_if_present_flag | 
          1 | 
          Integer | 
          Флаг, указывающий, должно ли сообщение заместить уже имеющееся с 
            совпадающими полями source address, destination address и 
            service_type |  
        
          | data_coding | 
          1 | 
          Integer | 
          Указывает на то, каким образом представлены данные. Может 
            принимать значения: Bits 7 6 5 4 3 2 1 0 Meaning 0 0 0 
            0 0 0 0 0 SMSC Default Alphabet 0 0 0 0 0 0 0 1 IA5 (CCITT 
            T.50)/ASCII (ANSI X3.4) (b) 0 0 0 0 0 0 1 0 Octet unspecified 
            (8-bit binary) (b) 0 0 0 0 0 0 1 1 Latin 1 (ISO-8859-1) (b) 0 
            0 0 0 0 1 0 0 Octet unspecified (8-bit binary) (a) 0 0 0 0 0 1 0 
            1 JIS (X 0208-1990) (b) 0 0 0 0 0 1 1 0 Cyrllic (ISO-8859-5) 
            (b) 0 0 0 0 0 1 1 1 Latin/Hebrew (ISO-8859-8) (b) 0 0 0 0 1 0 
            0 0 UCS2 (ISO/IEC-10646) (a) 0 0 0 0 1 0 0 1 Pictogram Encoding 
            (b) 0 0 0 0 1 0 1 0 ISO-2022-JP (Music Codes) (b) 0 0 0 0 1 0 
            1 1 reserved 0 0 0 0 1 1 0 0 reserved 0 0 0 0 1 1 0 1 Extended 
            Kanji JIS(X 0212-1990) (b) 0 0 0 0 1 1 1 0 KS C 5601 (b) 0 0 0 
            0 1 1 1 1 reserved : 1 0 1 1 1 1 1 1 reserved 1 1 0 0 x x x 
            x GSM MWI control - see [GSM 03.38] (d) 1 1 0 1 x x x x GSM MWI 
            control - see [GSM 03.38] (d) 1 1 1 0 x x x x reserved 1 1 1 1 
            x x x x GSM message class control - see [GSM 03.38] 
            (e)
  Notes: a. These coding schemes are common to 
            GSM, TDMA and CDMA. The SMPP protocol allows ESME applications to 
            use the same DCS value (i.e. the GSM 03.38 value) for all three 
            technologies. b. In cases where a Data Coding Scheme is defined 
            for TDMA and/ or CDMA but not defined for GSM, SMPP uses GSM 03.38 
            reserved values. c. There is no default setting for the 
            data_coding parameter. d. The data_coding parameter will evolve 
            to specify Character code settings only. Thus the recommended way to 
            specify GSM MWI control is by specifying the relevant settings in 
            the optional parameters _ms_msg_wait_facilities and 
            ms_validity. e. The data_coding parameter will evolve to 
            specify Character code settings only. Thus the recommended way to 
            specify GSM message class control is by specifying the relevant 
            setting in the optional parameter dest_addr_subunit.  |  
        
          | sm_default_msg_id | 
          1 | 
          Integer | 
          Указывает на "предопределенное" ("canned") сообщение, т. е. 
            заранее сохраненное на SMSC. Может принимать значение 0-254 (0 если 
            не используется). |  
        
          | sm_length | 
          1 | 
          Integer | 
          Длина в октетах следующего поля |  
        
          | short_message | 
          Var 0-254 | 
          Octet String | 
          Собственно, сообщение :). Обратим внимание, что это поле 
            расширено до 254 остетов (против 160-ти). Это связано с тем, что 
            возможна передача сообщений в различных 
      кодировках. |   
      
      Далее в пакете могут быть необязательные параметры в TLV 
      формате. Все они связаны с использованием дополнительных возможностей, 
      предоставляемых SMPP и в нашем конкретном случае не надобны. Еще раз хотим 
      обратить внимание, что в этой статье мы не собирались давать подробный 
      перевод спецификации протокола, равно как и документов GSM. Напротив, мы 
      хотели "спроецировать" тот необходимый минимум, который позволит создать 
      работающее SMS-приложение. Дальнейшее его развитие -- дело ума чести и 
      совести каждого :). Посему мы сейчас не станем детально останавливаться на 
      описании каждого поля (там, где было возможно, мы посторались указать на 
      наиболее употребительные значения). Позже мы приведем пример работающего 
      кода и многое станет более понятно. На вопросы, как обычно мы отвечаем в 
      форуме. 
       
      submit_sm_resp. command_id = 0x80000004
      Тело пакета submit_sm_resp состоит из следующих 
полей: 
      
      
        
        
          Field name 
          Size (octets) 
          Type 
          Description 
         
          | message_id | 
          Var. max 65 | 
          C-Octet String | 
          Идентификатор сообщения, назначенный SMSC  |   
      
      В том случае, если поле command_status заголовка 
      пакета не содержит нулевого значения (т. е. указывает на ошибку), 
      тело пакета не передается. Идентификатор, назначенный SMSC используется 
      для дальнейших операций с сообщениями, как то: запросы, удаление, 
      замещение. Кроме того, он же будет фигурировать в delivery_receipt-е. От 
      внимательного читателя не укрылось, что длина идентификатора в 65 октетов 
      (символов), вообще говоря, не позволяет хранить его ни в каком из цифровых 
      форматов. Тем не менее, на практике почти всегда это поле содержит 
      значение, укладывающееся в 32-х битное целое (по крайней мере, другого не 
      наблюдалось). Так что выбор формата хранения smsc_id целиком на совести 
      разработчика ESME ибо чаще всего эти значения хранятся в поле таблицы базы 
      данных, а поиск цифрового значения гораздо более эффективен, нежели 
      строки. 
      Формат представления даты в SMPP.
      В данной версии протокола все поля, связанные с датой и 
      временем должны быть представлены в формате “YYMMDDhhmmsstnnp” 
      где: 
      
        ‘YY’ последние две цифры года  (00-99) 
        ‘MM’ месяц  (01-12) 
        ‘DD’ день месяца  (01-31) 
        ‘hh’ час (00-23) 
        ‘mm’ минута (00-59) 
        ‘ss’ секунда (00-59) 
        ‘t’ десятая секунды (0-9) 
        ‘nn’ различие в четвертях часа между локальным временем и 
        временем  UTC(Universal Time Constant) (00-48). 
        ‘p’ =  “+”локальное время опережает UTC. 
        ‘p’ =  “-” локальное время отстает от UTC. 
        ‘p’ = “R” локальное время задано относительно времени SMSC. 
      В зависимости от значения параметра "p" (+/- или R) 
      различают абсолютный (+/-) или относительный (R) формат даты. Абсолютный 
      формат указывает на точно специфицированный момент времени (как показано 
      выше), а относительный -- промежуток времени относительно текущего времени 
      SMSC. Например, '020610233429000R' будет истолковано как 2 года, 6 
      месяцев, 10 дней, 23 часа, 34 минуты и 29 секунд от текущего времени 
      SMSC. 
      В ответах SMSC дается его локальное время в формате 
      “YYMMDDhhmmss”.  
      deliver_sm. command_id = 0x5 
      Формат пакета deliver_sm полностью совпадает с 
      форматом пакета submit_sm  (в части описанных обязательных 
      параметров), посему мы не будем здесь его еще раз повторять. Упомянем 
      только о специфике в значениях некоторых полей:  
      
        schedule_delivery_time не используется и выставляется в 0. 
        Поле validity_period не используется и выставляется в 0. 
        Поле registered_delivery указывает что необходимо 
        подтверждение ESME (ESME acknowledgement). Для отправки подтверждения 
        ESME   должно использовать пакет submit_sm со 
        специальным значением (см. выше) поля esm_class. 
        Поле replace_if_present_flag не используется и выставляется в 
        0. 
        Поле sm_default_msg_id не используется и выставляется в 0. 
        
      Напомним, что SMSC использует этот пакет как для доставки 
      входящих (для ESME) сообщений так и для передачи подтверждений доставки 
      (delivery_receipt). Тип сообщения (входящее/подтверждение) указывается, 
      как и для submit_sm, в поле esm_class:  
      
      Bits 7 6 5 4 3 2 1 0 Meaning Message Mode (bits 1-0) x 
      x x x x x x x not applicable - ignore bits 0 and 1   Message 
      Type (bits 5-2) x x 0 0 0 0 x x Default message Type (i.e. normal 
      message) x x 0 0 0 1 x x Short Message contains SMSC Delivery 
      Receipt x x 0 0 1 0 x x Short Message contains SME Delivery 
      Acknowledgement x x 0 0 1 1 x x reserved x x 0 1 0 0 x x Short 
      Message contains SME Manual/User Acknowledgment x x 0 1 0 1 x x 
      reserved x x 0 1 1 0 x x Short Message contains Conversation Abort 
      (Korean CDMA) x x 0 1 1 1 x x reserved x x 1 0 0 0 x x Short Message 
      contains Intermediate Delivery Notification all other values 
      reserved 
      
      deliver_sm_resp. command_id = 0x80000005 Формат 
      пакета deliver_sm_resp в точности совпадает с форматом пакета 
      submit_sm_resp с тем исключением, что поле message_id не 
      используется и выставляется в 0. 
      
      Формат подтверждения доставки. 
      Как уже говорилось, для поттверждения доставки SMSC 
      использует пакет deliver_sm со специальным (см. выше)  
      значением поля esm_class. Обычно оно содержит значение 0x4, но, как 
      видно, младшие два бита могут содержать любое значение. Сама информация 
      подтверждения содержится в поле short_message. Точное значение 
      этого поля зависит от производителя и модели SMSC, но, в большинстве 
      случаев, подчиняется рекомендованному формату: “id:IIIIIIIIII sub:SSS 
      dlvrd:DDD submit date:YYMMDDhhmm done date:YYMMDDhhmm stat:DDDDDDD err:E 
      text: . . . . . . . . .” Где:  
      
        
        
          Field name 
          Size (octets) 
          Type 
          Description 
         
          | id | 
          10 | 
          C-Octet String (Decimal) | 
          Идентификатор сообщения, назначенный SMSC  |  
        
          | sub  | 
          3 | 
          C-Octet String (Decimal) | 
          Количество посланных сообщений. Используеся, если сообщения 
            послано нескольким получателям. Дополняется ведущими нулями  |  
        
          | dlvrd  | 
          3 | 
          C-Octet String (Decimal) | 
          Количество доведенных сообщений. Используеся, если сообщения 
            послано нескольким получателям. Дополняется ведущими нулями  |  
        
          | submit date | 
          10 | 
          C-Octet Fixed Length String | 
          Время, когда сообщение было отправлено в формате 
        'YYMMDDhhmm' |  
        
          | done date  | 
          10 | 
          C-Octet Fixed Length String | 
          Время, когда сообщение достигло финального состояния 
            (доведено/не может быть доведено) в формате 'YYMMDDhhmm' |  
        
          | stat | 
          7 | 
          C-Octet Fixed Length String | 
          Состояние. (см. ниже) |  
        
          | err | 
          3 | 
          C-Octet Fixed Length String | 
          Может содержать код ошибки (если необходимо) |  
        
          | text | 
          20 | 
          C-Octet String | 
          Первые 20 символов исходного сообщения. |    
      
        
        
          State 
          Stat field value  
          Description 
         
          | DELIVERED | 
          DELIVRD | 
          Сообщение доведено получателю  |  
        
          | EXPIRED | 
          EXPIRED | 
          Истек срок годности сообщения  |  
        
          | DELETED | 
          DELETED | 
          Сообщение было удалено  |  
        
          | UNDELIVERABLE | 
          UNDELIV | 
          Сообщение не может быть доведено  |  
        
          | ACCEPTED | 
          ACCEPTD | 
          Было прочитано вручную от имени подписчика  |  
        
          | UNKNOWN | 
          UNKNOWN | 
          Сообщение в некорректном состоянии  |  
        
          | REJECTED | 
          REJECTD | 
          Сообщение отвергнуто  |   
      Unbind.
      Команды unbind и unbind_resp имеют значения 
      command_id 0x6 и 0x80000006 соответственно и не содержат тел (т. е. 
      состоят из одного header'а) 
      Заключение 
      Теперь, думается, мы знаем достаточно для того, чтобы 
      написать наше первое настоящее SMS-приложение, чем мы и займемся в 
      следующей статье. 
 
 |