结合VTS和BACnet协议栈源码分析Write Property读属性

          协议栈主要是针对应用层的编码,因此我们只需要结合VTS中的 BACnet Application Layer Detail 来对源码进行分析,  写属性源文件是wp.c,

这个文件中一共包含以下函数:

int wp_encode_apdu( uint8_t * apdu, uint8_t invoke_id , BACNET_WRITE_PROPERTY_DATA * wpdata);

int wp_decode_service_request( uint8_t * apdu, unsigned apdu_len,  BACNET_WRITE_PROPERTY_DATA * wpdata);


        先看看第一个函数,这是一个发送写属性,对具有写属性的PDU进行编码的函数

int wp_encode_apdu(
    uint8_t * apdu,
    uint8_t invoke_id,
    BACNET_WRITE_PROPERTY_DATA * wpdata)
{
    int apdu_len = 0;   /* total length of the apdu, return value */
    int len = 0;        /* total length of the apdu, return value */

    if (apdu) {
        apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;                                 
        apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);                              
        apdu[2] = invoke_id;                                                         
        apdu[3] = SERVICE_CONFIRMED_WRITE_PROPERTY;     /* service choice */          
        apdu_len = 4;
        len =
            encode_context_object_id(&apdu[apdu_len], 0, wpdata->object_type,
            wpdata->object_instance);
        apdu_len += len;
        len =
            encode_context_enumerated(&apdu[apdu_len], 1,
            wpdata->object_property);
        apdu_len += len;
        /* optional array index; ALL is -1 which is assumed when 0missing */
        if (wpdata->array_index != BACNET_ARRAY_ALL) {
            len =
                encode_context_unsigned(&apdu[apdu_len], 2,
                wpdata->array_index);
            apdu_len += len;
        }
        /* propertyValue */
        len = encode_opening_tag(&apdu[apdu_len], 3);
        apdu_len += len;
        for (len = 0; len < wpdata->application_data_len; len++) {
            apdu[apdu_len + len] = wpdata->application_data[len];
        }
        apdu_len += wpdata->application_data_len;
        len = encode_closing_tag(&apdu[apdu_len], 3);
        apdu_len += len;
        /* optional priority - 0 if not set, 1..16 if set */
        if (wpdata->priority != BACNET_NO_PRIORITY) {
            len =
                encode_context_unsigned(&apdu[apdu_len], 4, wpdata->priority);
            apdu_len += len;
        }
    }

    return apdu_len;
}

        

结合VTS和BACnet协议栈源码分析Write Property读属性_第1张图片

            PDU_TYPE_CONFIRMED_SERVICE_REQUEST的值被定义为0,被存储在apdu[0]中,同时在apdu[1]中存储的是函数     

encode_max_segs_max_apdu(...)返回的一个字节,这个字节的高低部分分别存储了最大分段数与最大apdu的信息。

          apdu[2]中存储 了invoke id,也就是VTS中的 Invoke ID = 105 这个信息。 apdu[3] = SERVICE_CONFIRMED_WRITE_PROPERTY,这里对应

了   VTS中的Write Property Request = 15 这个信息。
         
          接下来是调用了一个encode_context_object_id(....)函数,这个函数之前的文章中介绍过,

它内部先后调用了encode_tag(...)   和  encode_bacnet_object_id(.....)两个函数,这里不赘述,先看看VTS中究竟是怎样定义的:

        结合VTS和BACnet协议栈源码分析Write Property读属性_第2张图片
         和协议栈的代码一样,先是context tag编码的信息,然后是BACnet Object Identifier的信息。
         在 encode_bacnet_object_id(.....)   这个函数中,针对的是VTS中 Object Type 和 Instance Number,这两个内容进行编码的。代码的具体分析可以参考前面的文章。

结合VTS和BACnet协议栈源码分析Write Property读属性_第3张图片

          encode_context_enumerated(.....)这个函数的编码是根据Property Identifier这个内容编码的,具体针对的是present-value这个
 
   属性的ID进行编码,present-value这个属性的ID是85,同时这是一个上下文特定标记,与此相对应的标记编码为00011001。


结合VTS和BACnet协议栈源码分析Write Property读属性_第4张图片
       
          这里,设置的Real 值为44.0000,结合代码可以发现这里需要成对的opening_tag和closing_tag,如果有缺失的话证明报文出错。

结合VTS和BACnet协议栈源码分析Write Property读属性_第5张图片
           
          最后还有一个priority选项。

          值得注意的是,对于每一个参数都需要在编码过程中进行标识编码

           结合VTS和BACnet协议栈源码分析Write Property读属性_第6张图片

         


你可能感兴趣的:(bacnet)