[ORAN] FlexRIC Sevice Model (2): Encode/Decode
在定義好 Service Model 的 Indication 之後,
我們接著去修改 Encode/Decode 的相關程式,
位置的路徑一樣是位於: ~/flexric/src/sm/new_sm
在此路徑下, 有兩個資料夾: dec, enc, 分別對應於 decode 和 encode 的功能
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,
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 資料格式.
留言
張貼留言