[ORAN] FlexRIC Sevice Model (2): Encode/Decode

在定義好 Service Model 的 Indication 之後,
我們接著去修改 Encode/Decode 的相關程式,
位置的路徑一樣是位於: ~/flexric/src/sm/new_sm
在此路徑下, 有兩個資料夾: dec, enc, 分別對應於 decode 和 encode 的功能


其中, 我們也可以看到, 在 encode/decode 中也對應了三種格式:
ASN.1, fb (flatBuffer) 以及 plain, 對應於在 SM 建立的格式,
考慮到我們使用 plain 作為此次的範例, 相關的檔案就包括:
enc/new_enc_plain.h, enc/new_enc_plain.c, dec/new_dec_plain.h, dec/new_dec_plain.c,
其中, header 檔 (.h) 只定義了程式,不須修改, 和 SM 相關修改的範例如下:
  • enc/new_enc_plain.c:
    // 根據定義的 SM 資料格式長度宣告記憶體大小
    // 並把 SM 中的資料直接 memcpy 至傳送的資料格式中
    byte_array_t new_enc_ind_msg_plain(new_ind_msg_t const* ind_msg)
    {
      assert(ind_msg != NULL);
      byte_array_t ba = {0};

      size_t const sz = sizeof(ind_msg->len) + 
                      sizeof(new_ng_u_tunnel_stats_t)*ind_msg->len + 
                      sizeof(ind_msg->tstamp);
    // 長度為 SM 定義的格式加上 timestamp 長度
    //  printf("Size of the byte array = %lu\n", sz);

      ba.buf = malloc(sz); 
      assert(ba.buf != NULL && "Memory exhausted");

      memcpy(ba.buf, &ind_msg->len, sizeof(ind_msg->len));

      void* it = ba.buf + sizeof(ind_msg->len);
      for(uint32_t i = 0; i < ind_msg->len ; ++i){
        memcpy(it, &ind_msg->ngut[i], sizeof(ind_msg->ngut[i]));
        it += sizeof(ind_msg->ngut[i]);
      }

      memcpy(it, &ind_msg->tstamp, sizeof(ind_msg->tstamp));
      it += sizeof(ind_msg->tstamp);

      assert(it == ba.buf + sz && "Mismatch of data layout");

      ba.len = sz;
      return ba;
    }
     
  • dec/new_dec_plain.c:
    // 檢查資料大小是否符合最小的 SM 定義
    // 若符合則把 SM 大小的資料 (new_ng_u_tunnel_stats_t) 取出
    // 並檢查是否和 SM 定義的總長度符合
    new_ind_msg_t new_dec_ind_msg_plain(size_t len, uint8_t const ind_msg[len])
    {
      assert(next_pow2(len) >= sizeof(new_ind_msg_t) - sizeof(new_ng_u_tunnel_stats_t*) &&
    "Less bytes than the case where there are not active ngu Tunnel! Next pow2 trick used for aligned struct");
      new_ind_msg_t ret = {0};

      memcpy(&ret.len, ind_msg, sizeof(ret.len));
      if(ret.len > 0){
        ret.ngut = calloc(ret.len, sizeof(new_ng_u_tunnel_stats_t) );
        // 此物件用以取出定義的 SM 格式
        assert(ret.ngut != NULL && "memory exhausted");
      }

      void const* it = ind_msg + sizeof(ret.len);
      for(uint32_t i = 0; i < ret.len; ++i){
        memcpy(&ret.ngut[i], it, sizeof(ret.ngut[i]));
        it += sizeof(ret.ngut[i]); 
      }
     
      memcpy(&ret.tstamp, it, sizeof(ret.tstamp));
      it += sizeof(ret.tstamp);
      // timestamp 不包含於 SM 格式, 另外處理

      assert(it == &ind_msg[len] && "Mismatch of data layout");
      // 確定長度是否符合

      return ret;
    }
從上述 encode/decode 的實作中,
我們可以看到 plain 的 SM 資料格式, 就是直接將 SM 定義的資料欄位,
存放到記憶體空間中以 bytestream 的方式送出,
因此, encode/decode 雙方需要了解 SM 格式的長度資訊,
對 xApp 和 E2 Agent 而言, 這些傳送和接收的 byte, 
則需要進一步以對應 SM 定義的資料格式, e.g. uint64_t, 進行解讀,
也因此, 當加入一個新的 SM 服務, RIC, E2 Agent, xApp 都必須重新編譯,
以確保大家有共享的 SM 資料格式.

留言

熱門文章

LTE筆記: RSRP, RSSI and RSRQ

[WiFi] WiFi 網路的識別: BSS, ESS, SSID, ESSID, BSSID

LTE筆記: 5G NR Measurement Events