2014-07-25 161 views
2

所以我正在開發一個BACnet自動控制系統,我對它比較陌生,因爲這是我第一次使用BACnet。我已經使用asn1c編譯器將ASN.1協議轉換爲C格式。我有一個非常困難的時間找到一個清楚的例子,如何實現代碼的原因有很多。 1,我不完全確定ASN.1是如何工作的,2,現在代碼已經轉換爲C,它看起來截然不同,並且物理語法讓我感到困惑。我想知道是否有人能夠解釋ASN.1傳輸數據的實際過程。我讀過使用ASN.1的手機可以與超級計算機進行通信的情況,我想知道如何以及如果任何人有一個明確的「白癡證明」如何實際解碼和編碼可以從BACnet消息讀取和寫入的消息。下面我發佈了BACnetObjectIdentifierBACnet編碼/解碼ASN.1/C語法

  #include "BACnetObjectIdentifier.h" 
      main() 
      { 
      int 
      BACnetObjectIdentifier_constraint(asn_TYPE_descriptor_t *td, const void       
        asn_app_constraint_failed_f *ctfailcb, void *app_key) { 
     const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; 
     size_t size; 

      if(!sptr) { 
        _ASN_CTFAIL(app_key, td, sptr, 
        "%s: value not given (%s:%d)", 
        td->name, __FILE__, __LINE__); 
        return -1; 
        } 

    size = st->size; 

    if((size == 4)) { 
      /* Constraint check succeeded */ 
      return 0; 
    } else { 
      _ASN_CTFAIL(app_key, td, sptr, 
        "%s: constraint failed (%s:%d)", 
        td->name, __FILE__, __LINE__); 
      return -1; 
      } 
    } 
      static void 
     BACnetObjectIdentifier_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { 
      td->free_struct = asn_DEF_OCTET_STRING.free_struct; 
      td->print_struct = asn_DEF_OCTET_STRING.print_struct; 
      td->check_constraints = asn_DEF_OCTET_STRING.check_constraints; 
      td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder; 
      td->der_encoder = asn_DEF_OCTET_STRING.der_encoder; 
      td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder; 
      td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder; 
      td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder; 
      td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder; 
      if(!td->per_constraints){ 
       td->per_constraints = asn_DEF_OCTET_STRING.per_constraints; 
       td->elements  = asn_DEF_OCTET_STRING.elements; 
       td->elements_count = asn_DEF_OCTET_STRING.elements_count; 
       td->specifics  = asn_DEF_OCTET_STRING.specifics; 
       } 

      void 
      BACnetObjectIdentifier_free(asn_TYPE_descriptor_t *td, 
       void *struct_ptr, int contents_only) { 
       BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
       td->free_struct(td, struct_ptr, contents_only); 
       } 

       int 
     BACnetObjectIdentifier_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, 
      int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { 
      BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
      return td->print_struct(td, struct_ptr, ilevel, cb, app_key); 
      } 

      asn_dec_rval_t 
BACnetObjectIdentifier_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, 
       void **structure, const void *bufptr, size_t size, int tag_mode) { 
       BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
      return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); 
       } 

      asn_enc_rval_t 
      BACnetObjectIdentifier_encode_der(asn_TYPE_descriptor_t *td, 
        void *structure, int tag_mode, ber_tlv_tag_t tag, 
        asn_app_consume_bytes_f *cb, void *app_key) { 
        BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
        return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); 
        } 

       asn_dec_rval_t 
      BACnetObjectIdentifier_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, 

          void **structure, const void *bufptr, size_t size, int tag_mode) { 
      BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
      return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); 
      } 

      asn_enc_rval_t 
      BACnetObjectIdentifier_encode_der(asn_TYPE_descriptor_t *td, 
      void *structure, int tag_mode, ber_tlv_tag_t tag, 
      asn_app_consume_bytes_f *cb, void *app_key) { 
      BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
      return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); 
      } 

     asn_dec_rval_t 
     BACnetObjectIdentifier_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, 
      void **structure, const char *opt_mname, const void *bufptr, size_t size) { 
      BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
      return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); 
      } 

      asn_enc_rval_t 
       BACnetObjectIdentifier_encode_xer(asn_TYPE_descriptor_t *td, void *structure, 
       int ilevel, enum xer_encoder_flags_e flags, 
       asn_app_consume_bytes_f *cb, void *app_key) { 
       BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
       return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); 
       } 

       asn_dec_rval_t 
       BACnetObjectIdentifier_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, 
       asn_per_constraints_t *constraints, void **structure, asn_per_data_t     *per_data) { 
      BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
      return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); 
       } 

      asn_enc_rval_t 
      BACnetObjectIdentifier_encode_uper(asn_TYPE_descriptor_t *td, 
        asn_per_constraints_t *constraints, 
        void *structure, asn_per_outp_t *per_out) { 
        BACnetObjectIdentifier_1_inherit_TYPE_descriptor(td); 
        return td->uper_encoder(td, constraints, structure, per_out); 
       } 

       static asn_per_constraints_t   asn_PER_type_BACnetObjectIdentifier_constr_1 GCC_NOTUSED = { 
      { APC_UNCONSTRAINED, -1, -1, 0, 0 }, 
        { APC_CONSTRAINED,  0, 0, 4, 4 }  /* (SIZE(4..4)) */, 
     0, 0 /* No PER value map */ 
     }; 
     static ber_tlv_tag_t asn_DEF_BACnetObjectIdentifier_tags_1[] = { 
      (ASN_TAG_CLASS_APPLICATION | (12 << 2)), 
     (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) 
      }; 
      asn_TYPE_descriptor_t asn_DEF_BACnetObjectIdentifier = { 
      "BACnetObjectIdentifier", 
      "BACnetObjectIdentifier", 
      BACnetObjectIdentifier_free, 
      BACnetObjectIdentifier_print, 
      BACnetObjectIdentifier_constraint, 
      BACnetObjectIdentifier_decode_ber, 
      BACnetObjectIdentifier_encode_der, 
      BACnetObjectIdentifier_decode_xer, 
      BACnetObjectIdentifier_encode_xer, 
      BACnetObjectIdentifier_decode_uper, 
      BACnetObjectIdentifier_encode_uper, 
      0,  /* Use generic outmost tag fetcher */ 
      asn_DEF_BACnetObjectIdentifier_tags_1, 
       sizeof(asn_DEF_BACnetObjectIdentifier_tags_1) 
       /sizeof(asn_DEF_BACnetObjectIdentifier_tags_1[0]) - 1, /* 1 */ 
       asn_DEF_BACnetObjectIdentifier_tags_1, /* Same as above */ 
       sizeof(asn_DEF_BACnetObjectIdentifier_tags_1) 
       /sizeof(asn_DEF_BACnetObjectIdentifier_tags_1[0]), /* 2 */ 
        &asn_PER_type_BACnetObjectIdentifier_constr_1, 
        0, 0, /* No members */ 
       0  /* No specifics */ 
        }; 
       } 

上面的代碼是asn1c編譯器生成的代碼。任何幫助是極大的讚賞。

回答

1

您需要的是ASN.1的介紹和您正在使用的工具的介紹。對於前者,你可能從這裏開始:http://www.obj-sys.com/resources/links_asn1_info.php。後者無法幫助你。

爲了幫助您定位,一個非常簡要的摘要: ASN.1是抽象語法表示法。它是描述摘要中消息語法的符號。 「在抽象中」的意思是,例如,使用符號表示一個整數跟在序列中的另一個整數之後,但是你沒有指定那些整數在傳輸中是如何實際表示的(例如,將使用多少位)? 。當您將抽象符號與一組編碼規則(例如BER,PER;編碼規則標準化 - 您不寫它們)組合時,抽象符號就變得具體。編碼規則結合抽象語法完全指定了傳輸的內容。

代碼生成工具的功能在概念上很簡單。他們閱讀ASN.1描述並以您最喜歡的編程語言生成數據結構,該語言對來自ASN.1的消息進行建模,以及根據您選擇的一組編碼規則對這些數據結構進行編碼/解碼的相應消息。作爲程序員,您可以填充數據結構,調用編碼方法,並接收根據您選擇的規則編碼的ASN.1消息(例如BER)。

+0

我從您使用XER的其他問題中看到。這是另一組標準化的編碼規則。它不是指定一個二進制編碼,而是指定一個文本編碼,它是用XML編碼的。 – Kevin

0

你真正需要的是Ashrae 135-2012(或更高版本)標準的副本。 (不幸的是非免費 - 儘管勘誤和簽署是免費的)。

ASN1只是描述了一些編碼規則,但這不是因爲我的電子郵件是用base64編碼的,如果你閱讀base64,你可以閱讀電子郵件。您還需要了解其他標題,上下文,規則和語義。

在Ashrae 135標準中,編碼,類型,枚舉和服務代碼是完全詳細的。這種信息對於理解和「讀取」BACnet數據包非常重要。

使用Wireshark查看和打開一些捕獲的數據包,確實也有幫助,以瞭解如何根據各種消息上下文列出和發送信息。

您也可以選擇免費或非免費的C或Java或C#(或其他)BACnet通信協議實現,並使用它。