chapter 04-03

資料數值的存取 (模組端程式) (基本模式)

此章節說明內部模組如何存取資料數值.


變數格式的說明

使用的資料模型範例, 參考 #02-02#.


[struct mcm_service_session_t *this_session]
請求端的連線資訊. [詳細]


[char *mask_path]
取得 group 的資訊的路徑. [詳細]


[char *mix_path]
存取多個 entry 的路徑. [詳細]


[char *full_path]
存取的目標 entry 或 member 的路徑. [詳細]


[char *insert_path]
在增加 entry 時, 指定要插入到哪個 entry 之前. [詳細]


存取 member 資料的變數的型態
[詳細]


存取 entry 資料的變數的型態
[詳細]


資料數值存取的模式的說明

在 mcm_daemon 處理資料的流程中 [詳細] :
在 [A03] [B04] 的點, 內部模組可以選擇是要存取新進資料區的資料還是系統資料區的資料.

在取得資料數值的情況

[MCM_DTYPE_FLAG_TD data_access]
要取出哪邊的資料.
MCM_DATA_ACCESS_METHOD
(mint_cm/mcm_lib/mcm_lheader/mcm_control.h)
MCM_DACCESS_SYS 從系統資料區
MCM_DACCESS_NEW 從新進資料區
MCM_DACCESS_AUTO 優先從新進資料區, 沒有的話才從系統資料區

使用 MCM_DACCESS_SYS 或 MCM_DACCESS_NEW 取得資料時, 對應的區域不一定有資料.
各種資料狀態下要注意的 :
模式 資料狀態 行為
MCM_DACCESS_SYS MCM_DSCHANGE_NONE 允許的操作
MCM_DSCHANGE_SET 允許的操作
MCM_DSCHANGE_ADD 禁止的操作
增加的資料會放在新進資料區, 無法從系統資料區取得資料
MCM_DSCHANGE_DEL 允許的操作
MCM_DACCESS_NEW MCM_DSCHANGE_NONE 禁止的操作
資料沒做修改不會出現在新進資料區
MCM_DSCHANGE_SET 允許的操作
MCM_DSCHANGE_ADD 允許的操作
MCM_DSCHANGE_DEL 禁止的操作
只是刪除資料, 新進資料區不會有資料

在修改資料數值的情況

[MCM_DTYPE_FLAG_TD data_access]
要如何修改資料數值.
MCM_DATA_ACCESS_METHOD
(mint_cm/mcm_lib/mcm_lheader/mcm_control.h)
MCM_DACCESS_SYS 直接修改系統資料區的資料
MCM_DACCESS_NEW
設定資料 將設定的資料放到資料庫的新進資料區, 並標註資料被設定
增加資料 在資料庫增加紀錄, 並將增加的資料放到新進資料區, 並標註資料被增加
刪除資料 標註資料被刪除
外部程式修改資料是使用此模式

MCM_DACCESS_SYS
01.  被修改的資料不會被貼上狀態.
02.  在 mcm_daemon 處理資料的流程中 [詳細][B], 如果資料有錯誤, 在 [B06] 的點 mcm_daemon 會放棄新進資料區的資料恢復成原始資料, 使用此模式會直接修改系統資料區的資料, 所以在 [B06] 的點發生資料錯誤需要恢復資料時, 被修改的資料不會恢復成沒被修改之前的數值.

MCM_DACCESS_NEW
01.  被修改的資料會依照 mcm_daemon 處理資料的流程處理 [詳細][B03][B06].
02.  要修改的資料已經被使用 MCM_DACCESS_NEW 模式修改過的話, 會直接修改放在新進資料區的資料.

在 mcm_daemon 處理資料的流程中 [詳細][B], 在 [B03] 的處理方式 :
操作前 操作方式 操作後
系統區 新進區 系統區 新進區
原資料 設定資料
MCM_DACCESS_SYS 模式
新資料
增加資料
MCM_DACCESS_SYS 模式
新資料
原資料 刪除資料
MCM_DACCESS_SYS 模式
原資料 設定資料
MCM_DACCESS_NEW 模式
原資料 新資料
增加資料
MCM_DACCESS_NEW 模式
新資料
原資料 刪除資料
MCM_DACCESS_NEW 模式
原資料

在 mcm_daemon 處理資料的流程中 [詳細][B], 在 [B06] 的處理方式 :
操作方式 處理前 套用資料 放棄資料
系統區 新進區 系統區 新進區 系統區 新進區
設定資料
MCM_DACCESS_NEW 模式
原資料 新資料 新資料 原資料
增加資料
MCM_DACCESS_NEW 模式
新資料 新資料
刪除資料
MCM_DACCESS_NEW 模式
原資料 原資料

在各種情況下使用上的注意事項和限制 :
操作 資料目前的狀態 行為
設定資料
MCM_DACCESS_SYS 模式
資料沒被修改
MCM_DSCHANGE_NONE
01.  允許的操作
02.  設定系統資料區的資料
03.  資料狀態不變
04.  發生 [放棄資料] 處理時, 無法恢復資料
資料被設定
MCM_DSCHANGE_SET
01.  允許的操作
02.  設定系統資料區的資料
03.  資料狀態不變
04.  發生 [套用資料] 處理時, 新進資料區的資料後會套用回系統資料區, 對系統資料區做設定最後會被覆蓋
05.  發生 [放棄資料] 處理時, 無法恢復資料
資料被增加
MCM_DSCHANGE_ADD
01.  禁止的操作
02.  增加的資料會放在新進資料區, 所以在系統資料區沒有資料設定
資料被刪除
MCM_DSCHANGE_DEL
01.  允許的操作
02.  設定系統資料區的資料
03.  資料狀態不變
04.  發生 [套用資料] 處理時, 此筆資料會被刪除, 對系統資料區做設定最後會無效
05.  發生 [放棄資料] 處理時, 無法恢復資料
增加資料
MCM_DACCESS_SYS 模式
parent-entry 的資料
沒被修改
MCM_DSCHANGE_NONE
01.  允許的操作
02.  修改系統資料區的資料
03.  資料狀態不變
04.  發生 [放棄資料] 處理時, 無法恢復資料
parent-entry 的資料
被設定
MCM_DSCHANGE_SET
01.  允許的操作
02.  增加資料到系統資料區
03.  資料狀態不變
04.  發生 [放棄資料] 處理時, 無法恢復資料
parent-entry 的資料
被增加
MCM_DSCHANGE_ADD
01.  禁止的操作
02.  如果 parent-entry 發生 [放棄資料] 處理, parent-entry 會被刪除, 無法跨層增加資料
parent-entry 的資料
被刪除
MCM_DSCHANGE_DEL
01.  禁止的操作
02.  parent-entry 在刪除的狀態時, 所有的 child-entry 也會一併變成刪除的狀態, 使用 MCM_DACCESS_SYS 增加的資料不會含有狀態, 不符合規則
刪除資料
MCM_DACCESS_SYS 模式
資料沒被修改
MCM_DSCHANGE_NONE
01.  允許的操作
02.  刪除此筆資料
03.  發生 [放棄資料] 處理時, 無法恢復資料
資料被設定
MCM_DSCHANGE_SET
01.  允許的操作
02.  刪除此筆資料
03.  發生 [放棄資料] 處理時, 無法恢復資料
資料被增加
MCM_DSCHANGE_ADD
01.  允許的操作
02.  刪除此筆資料
03.  發生 [放棄資料] 處理時, 無法恢復資料
資料被刪除
MCM_DSCHANGE_DEL
01.  允許的操作
02.  刪除此筆資料
03.  發生 [放棄資料] 處理時, 無法恢復資料
設定資料
MCM_DACCESS_NEW 模式
資料沒被修改
MCM_DSCHANGE_NONE
01.  允許的操作
02.  設定的資料放在新進資料區
03.  資料狀態改為 MCM_DSCHANGE_SET
04.  發生 [放棄資料] 處理時, 可以恢復資料
資料被設定
MCM_DSCHANGE_SET
01.  允許的操作
02.  設定新進資料區的資料
03.  資料狀態不變
04.  發生 [放棄資料] 處理時, 可以恢復資料
資料被增加
MCM_DSCHANGE_ADD
01.  允許的操作
02.  設定新進資料區的資料
03.  資料狀態不變
04.  發生 [放棄資料] 處理時, 可以恢復資料
資料被刪除
MCM_DSCHANGE_DEL
01.  禁止的操作
02.  刪除資料並不會在新進資料區放置資料, 所以在新進資料區沒有資料可以修改
增加資料
MCM_DACCESS_NEW 模式
parent-entry 的資料
沒被修改
MCM_DSCHANGE_NONE
01.  允許的操作
02.  增加資料到系統資料區
03.  資料狀態改為 MCM_DSCHANGE_ADD
04.  發生 [放棄資料] 處理時, 可以恢復資料
parent-entry 的資料
被設定
MCM_DSCHANGE_SET
01.  允許的操作
02.  增加資料到系統資料區
03.  資料狀態改為 MCM_DSCHANGE_ADD
04.  發生 [放棄資料] 處理時, 可以恢復資料
parent-entry 的資料
被增加
MCM_DSCHANGE_ADD
01.  允許的操作
02.  增加資料到系統資料區
03.  資料狀態改為 MCM_DSCHANGE_ADD
04.  發生 [放棄資料] 處理時, 可以恢復資料
parent-entry 的資料
被刪除
MCM_DSCHANGE_DEL
01.  禁止的操作
02.  parent-entry 在刪除的狀態時, 所有的 child-entry 也會一併變成刪除的狀態, 使用 MCM_DACCESS_NEW 增加的資料會是增加狀態, 不符合規則
刪除資料
MCM_DACCESS_NEW 模式
資料沒被修改
MCM_DSCHANGE_NONE
01.  允許的操作
02.  複製系統資料區資料到新進資料區
03.  資料狀態改為 MCM_DSCHANGE_DEL
04.  發生 [放棄資料] 處理時, 可以恢復資料
資料被設定
MCM_DSCHANGE_SET
01.  允許的操作
02.  資料狀態改為 MCM_DSCHANGE_DEL
03.  發生 [套用資料] 處理時, 此筆資料會被刪除, 原本對新進資料區做設定最後會無效
04.  發生 [放棄資料] 處理時, 可以恢復資料
資料被增加
MCM_DSCHANGE_ADD
01.  禁止的操作
02.  資料狀態已經是增加, 無法改為刪除
資料被刪除
MCM_DSCHANGE_DEL
01.  允許的操作
02.  資料狀態不變
03.  發生 [放棄資料] 處理時, 可以恢復資料


可用的函式

mcm_config_get_max_count_by_path
取得資料筆數上限, 也就是資料模型中的 $(max) 值.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
mask_path
目標的路徑 [詳細]
MCM_DTYPE_EK_TD *
count_buf
紀錄資料筆數的緩衝
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS 錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 可以是唯讀或讀寫.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RO;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_max_count_test_01";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_max_count_test_01(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1;
    MCM_DTYPE_EK_TD max_count;

    // 範例 : 取得 device.system 的資料筆數上限.
    path1 = "device.system";
    if(mcm_config_get_max_count_by_path(this_session, path1, &max_count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_max_count_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[max-count] %s = " MCM_DTYPE_EK_PF, path1, max_count);

    // 範例 : 取得 device.vap.* 的資料筆數上限.
    path1 = "device.vap.*";
    if(mcm_config_get_max_count_by_path(this_session, path1, &max_count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_max_count_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[max-count] %s = " MCM_DTYPE_EK_PF, path1, max_count);

    // 範例 : 取得 device.vap.*.station.* 的資料筆數上限.
    path1 = "device.vap.*.station.*";
    if(mcm_config_get_max_count_by_path(this_session, path1, &max_count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_max_count_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[max-count] %s = " MCM_DTYPE_EK_PF, path1, max_count);

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


除了上述方式外, 可以使用另一種方式取得 group 的資料筆數上限. [詳細]

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RO;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_max_count_test_02";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_max_count_test_02(
    struct mcm_service_session_t *this_session)
{
    char *path1;

    // 範例 : 取得 device.system 的資料筆數上限.
    path1 = "device.system";
    DMSG("[max-count] %s = " MCM_DTYPE_EK_PF, path1, MCM_MCOUNT_DEVICE_SYSTEM_MAX_COUNT);

    // 範例 : 取得 device.vap.* 的資料筆數上限.
    path1 = "device.vap.*";
    DMSG("[max-count] %s = " MCM_DTYPE_EK_PF, path1, MCM_MCOUNT_DEVICE_VAP_MAX_COUNT);

    // 範例 : 取得 device.vap.*.station.* 的資料筆數上限.
    path1 = "device.vap.*.station.*";
    DMSG("[max-count] %s = " MCM_DTYPE_EK_PF, path1, MCM_MCOUNT_DEVICE_VAP_STATION_MAX_COUNT);

    return MCM_RCODE_PASS;
}

mcm_config_get_count_by_path
取得目前的資料筆數.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
mix_path
目標的路徑 [詳細]
[index / key 模式]
MCM_DTYPE_EK_TD *
count_buf
紀錄資料筆數的緩衝
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 可以是唯讀或讀寫.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RO;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_count_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_count_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1;
    MCM_DTYPE_EK_TD count;

    // 範例 : 取得 device.system 的資料筆數.
    path1 = "device.system";
    if(mcm_config_get_count_by_path(this_session, path1, &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_count_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[count] %s = " MCM_DTYPE_EK_PF, path1, count);

    // 範例 : 取得 device.vap.* 的資料筆數.
    path1 = "device.vap.*";
    if(mcm_config_get_count_by_path(this_session, path1, &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_count_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[count] %s = " MCM_DTYPE_EK_PF, path1, count);

    // 範例 : 取得 device.vap.@1.station.* 的資料筆數.
    path1 = "device.vap.@1.station.*";
    if(mcm_config_get_count_by_path(this_session, path1, &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_count_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[count] %s = " MCM_DTYPE_EK_PF, path1, count);

    // 範例 : 取得 device.vap.#23.station.* 的資料筆數.
    path1 = "device.vap.#23.station.*";
    if(mcm_config_get_count_by_path(this_session, path1, &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_count_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[count] %s = " MCM_DTYPE_EK_PF, path1, count);

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

mcm_config_get_alone_by_path
讀出 member 的資料.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
full_path
目標的路徑 [詳細]
[member 格式][index / key 模式]
MCM_DTYPE_FLAG_TD
data_access
要使用何種模式 [詳細]
void *
data_buf
紀錄資料的變數的緩衝 (變數的資料型態 [詳細])
回傳 說明
== MCM_DACCESS_SYS 成功, 從系統資料區讀出資料
== MCM_DACCESS_NEW 成功, 從新進資料區讀出資料
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 可以是唯讀或讀寫.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;
    MCM_DTYPE_S_TD date[MCM_BSIZE_DEVICE_SYSTEM_DATE];
    MCM_DTYPE_RK_TD rule;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 範例-02 : 設定 device.system.date
    path1 = "device.system.date";
    snprintf(date, sizeof(date), "2013/05/%02u", rand() % 30);
    DMSG("[set-alone] %s = " MCM_DTYPE_S_PF, path1, date);
    if(mcm_lulib_set_alone(&self_lulib, path1, date, strlen(date)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_set_alone(%s) fail", path1);
        goto FREE_02;
    }

    // 範例-03 : 設定 device.vap.#15.station.@1.rule
    path1 = "device.vap.#15.station.@1.rule";
    rule = rand() % 50;
    DMSG("[set-alone] %s = " MCM_DTYPE_RK_PF, path1, rule);
    if(mcm_lulib_set_alone(&self_lulib, path1, &rule, sizeof(rule)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_set_alone(%s) fail", path1);
        goto FREE_02;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_alone_value_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_alone_value_test(
    struct mcm_service_session_t *this_session)
{
    int fret;
    char *path1;
    MCM_DTYPE_S_TD descript[MCM_BSIZE_DEVICE_DESCRIPT];
    MCM_DTYPE_B_TD serial_number[MCM_BSIZE_DEVICE_SERIAL_NUMBER];
    MCM_DTYPE_S_TD date[MCM_BSIZE_DEVICE_SYSTEM_DATE];
    MCM_DTYPE_RK_TD rule;

    path1 = "device.descript";
    // 範例-01a : 取得 device.descript (SYS 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_SYS, descript);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][SYS ] %s = " MCM_DTYPE_S_PF, path1, descript);
    // 範例-01b : 取得 device.descript (AUTO 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_AUTO, descript);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][AUTO] %s = " MCM_DTYPE_S_PF " [%s]",
         path1, descript, fret == MCM_DACCESS_SYS ? "SYS" : "NEW");

    path1 = "device.serial_number";
    // 範例-01c : 取得 device.serial_number (SYS 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_SYS, serial_number);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][SYS ] %s = "
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF,
         path1,
         serial_number[0], serial_number[1], serial_number[2], serial_number[3],
         serial_number[4], serial_number[5], serial_number[6], serial_number[7],
         serial_number[8], serial_number[9]);
    // 範例-01d : 取得 device.serial_number (AUTO 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_AUTO, serial_number);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][AUTO] %s = "
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF " [%s]",
         path1,
         serial_number[0], serial_number[1], serial_number[2], serial_number[3],
         serial_number[4], serial_number[5], serial_number[6], serial_number[7],
         serial_number[8], serial_number[9], fret == MCM_DACCESS_SYS ? "SYS" : "NEW");

    path1 = "device.system.date";
    // 範例-02a : 取得 device.system.date (SYS 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_SYS, date);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][SYS ] %s = " MCM_DTYPE_S_PF, path1, date);
    // 範例-02b : 取得 device.system.date (NEW 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_NEW, date);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][NEW ] %s = " MCM_DTYPE_S_PF, path1, date);
    // 範例-02c : 取得 device.system.date (AUTO 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_AUTO, date);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][AUTO] %s = " MCM_DTYPE_S_PF " [%s]",
         path1, date, fret == MCM_DACCESS_SYS ? "SYS" : "NEW");

    path1 = "device.vap.#15.station.@1.rule";
    // 範例-03a : 取得 device.vap.#15.station.@1.rule (SYS 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_SYS, &rule);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][SYS ] %s = " MCM_DTYPE_RK_PF, path1, rule);
    // 範例-03b : 取得 device.vap.#15.station.@1.rule (NEW 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_NEW, &rule);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][NEW ] %s = " MCM_DTYPE_RK_PF, path1, rule);
    // 範例-03c : 取得 device.vap.#15.station.@1.rule (AUTO 模式)
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_AUTO, &rule);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-alone][AUTO] %s = " MCM_DTYPE_RK_PF " [%s]",
         path1, rule, fret == MCM_DACCESS_SYS ? "SYS" : "NEW");

FREE_01:
    return fret;
}

mcm_config_set_alone_by_path
將資料寫入 member.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
full_path
目標的路徑 [詳細]
[member 格式][index / key 模式]
MCM_DTYPE_FLAG_TD
data_access
要使用何種模式 [詳細]
void *
data_con
寫入的資料 (變數的資料型態 [詳細])
MCM_DTYPE_USIZE_TD
data_len
寫入的資料的長度
字串類型填入字串長度, 其他類型填入變數大小
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 必須是讀寫.
02.  對於 ek 類型的 member 是唯讀的, 不可寫入.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;
    MCM_DTYPE_IUI_TD channel;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 範例-03 : 設定 device.vap.#8.channel
    path1 = "device.vap.#8.channel";
    channel = rand() % 200;
    DMSG("[set-alone] %s = " MCM_DTYPE_IUI_PF, path1, channel);
    if(mcm_lulib_set_alone(&self_lulib, path1, &channel, sizeof(channel)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_set_alone(%s) fail", path1);
        goto FREE_02;
    }

    // 範例-04 : 增加 device.vap.@3.station.#1
    path1 = "device.vap.@3.station.#1";
    DMSG("[add-entry] %s", path1);
    if(mcm_lulib_add_entry(&self_lulib, path1, NULL, NULL, 0) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_add_entry(%s) fail", path1);
        goto FREE_02;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_set_alone_value_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_set_alone_value_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1;
    MCM_DTYPE_S_TD descript[MCM_BSIZE_DEVICE_DESCRIPT];
    MCM_DTYPE_B_TD serial_number[MCM_BSIZE_DEVICE_SERIAL_NUMBER];
    MCM_DTYPE_IULL_TD uptime;
    MCM_DTYPE_IUI_TD channel;
    MCM_DTYPE_RK_TD rule;
    MCM_DTYPE_USIZE_TD i;

    srand(time(NULL));

    // 範例-01a : 設定 device.descript (SYS 模式)
    path1 = "device.descript";
    snprintf(descript, sizeof(descript), "network-device-%02u", rand() % 100);
    DMSG("[set-alone][SYS] %s = " MCM_DTYPE_S_PF, path1, descript);
    if(mcm_config_set_alone_by_path(this_session, path1, MCM_DACCESS_SYS, descript,
                                    strlen(descript)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-01b : 設定 device.serial_number (SYS 模式)
    path1 = "device.serial_number";
    for(i = 0; i < sizeof(serial_number); i++)
        serial_number[i] = rand() % 256;
    DMSG("[set-alone][SYS] %s = "
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF,
         path1,
         serial_number[0], serial_number[1], serial_number[2], serial_number[3],
         serial_number[4], serial_number[5], serial_number[6], serial_number[7],
         serial_number[8], serial_number[9]);
    if(mcm_config_set_alone_by_path(this_session, path1, MCM_DACCESS_SYS, serial_number,
                                    sizeof(serial_number)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-02 : 設定 device.system.uptime (NEW 模式)
    path1 = "device.system.uptime";
    uptime = rand();
    DMSG("[set-alone][NEW] %s = " MCM_DTYPE_IULL_PF, path1, uptime);
    if(mcm_config_set_alone_by_path(this_session, path1, MCM_DACCESS_NEW, &uptime, sizeof(uptime))
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-03 : 設定 device.vap.#8.channel (NEW 模式)
    path1 = "device.vap.#8.channel";
    channel = rand() % 200;
    DMSG("[set-alone][NEW] %s = " MCM_DTYPE_IUI_PF, path1, channel);
    if(mcm_config_set_alone_by_path(this_session, path1, MCM_DACCESS_NEW, &channel,
                                    sizeof(channel)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-04 : 設定 device.vap.@3.station.#1.rule (NEW 模式)
    path1 = "device.vap.@3.station.#1.rule";
    rule = rand() % 50;
    DMSG("[set-alone][NEW] %s = " MCM_DTYPE_RK_PF, path1, rule);
    if(mcm_config_set_alone_by_path(this_session, path1, MCM_DACCESS_NEW, &rule, sizeof(rule))
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

mcm_config_get_entry_by_path
讀出 entry 的資料.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
full_path
目標的路徑 [詳細]
[entry 格式][index / key 模式]
MCM_DTYPE_FLAG_TD
data_access
要使用何種模式 [詳細]
void *
data_buf
紀錄資料的變數的緩衝 (變數的資料型態 [詳細])
回傳 說明
== MCM_DACCESS_SYS 成功, 從系統資料區讀出資料
== MCM_DACCESS_NEW 成功, 從新進資料區讀出資料
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 可以是唯讀或讀寫.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;
    struct mcm_dv_device_system_t system_v;
    struct mcm_dv_device_vap_station_t station_v;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 範例-02 : 設定 device.system
    path1 = "device.system";
    memset(&system_v, 0, sizeof(system_v));
    snprintf(system_v.date, sizeof(system_v.date), "2010/11/%u", rand() % 30);
    snprintf(system_v.ip_addr, sizeof(system_v.ip_addr), "192.168.11.%u", rand() % 250);
    system_v.uptime = rand();
    system_v.loading = ((MCM_DTYPE_FD_TD) 25000) / ((rand() % 100) + 1);
    DMSG("[set-entry] %s.date = " MCM_DTYPE_S_PF, path1, system_v.date);
    DMSG("[set-entry] %s.ip_addr = " MCM_DTYPE_S_PF, path1, system_v.ip_addr);
    DMSG("[set-entry] %s.uptime = " MCM_DTYPE_IULL_PF, path1, system_v.uptime);
    DMSG("[set-entry] %s.loading = " MCM_DTYPE_FD_PF, path1, system_v.loading);
    if(mcm_lulib_set_entry(&self_lulib, path1, &system_v, sizeof(system_v)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_set_entry(%s) fail", path1);
        goto FREE_02;
    }

    // 範例-03 : 設定 device.vap.@2.station.@1
    path1 = "device.vap.@2.station.@1";
    memset(&station_v, 0, sizeof(station_v));
    snprintf(station_v.mac_addr, sizeof(station_v.mac_addr), "00:22:44:66:BB:%02X", rand() % 255);
    station_v.rule = rand() % 50;
    DMSG("[set-entry] %s.mac_addr = " MCM_DTYPE_S_PF, path1, station_v.mac_addr);
    DMSG("[set-entry] %s.rule = " MCM_DTYPE_RK_PF, path1, station_v.rule);
    if(mcm_lulib_set_entry(&self_lulib, path1, &station_v, sizeof(station_v)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_set_entry(%s) fail", path1);
        goto FREE_02;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_entry_value_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_entry_value_test(
    struct mcm_service_session_t *this_session)
{
    int fret;
    char *path1, *source;
    struct mcm_dv_device_t device_v;
    struct mcm_dv_device_system_t system_v;
    struct mcm_dv_device_vap_station_t station_v;

    path1 = "device";
    // 範例-01a : 取得 device (SYS 模式).
    fret = mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_SYS, &device_v);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-entry][SYS ] %s.descript = " MCM_DTYPE_S_PF, path1, device_v.descript);
    DMSG("[get-entry][SYS ] %s.serial_number = "
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF,
         path1,
         device_v.serial_number[0], device_v.serial_number[1], device_v.serial_number[2],
         device_v.serial_number[3], device_v.serial_number[4], device_v.serial_number[5],
         device_v.serial_number[6], device_v.serial_number[7], device_v.serial_number[8],
         device_v.serial_number[9]);
    // 範例-01b : 取得 device (AUTO 模式).
    fret = mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_AUTO, &device_v);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    source = fret == MCM_DACCESS_SYS ? "SYS" : "NEW";
    DMSG("[get-entry][AUTO] %s.descript = " MCM_DTYPE_S_PF " [%s]",
         path1, device_v.descript, source);
    DMSG("[get-entry][AUTO] %s.serial_number = "
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF " [%s]",
         path1,
         device_v.serial_number[0], device_v.serial_number[1], device_v.serial_number[2],
         device_v.serial_number[3], device_v.serial_number[4], device_v.serial_number[5],
         device_v.serial_number[6], device_v.serial_number[7], device_v.serial_number[8],
         device_v.serial_number[9], source);

    path1 = "device.system";
    // 範例-02a : 取得 device.system (SYS 模式)
    fret = mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_SYS, &system_v);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-entry][SYS ] %s.date = " MCM_DTYPE_S_PF, path1, system_v.date);
    DMSG("[get-entry][SYS ] %s.ip_addr = " MCM_DTYPE_S_PF, path1, system_v.ip_addr);
    DMSG("[get-entry][SYS ] %s.uptime = " MCM_DTYPE_IULL_PF, path1, system_v.uptime);
    DMSG("[get-entry][SYS ] %s.loading = " MCM_DTYPE_FD_PF, path1, system_v.loading);
    // 範例-02b : 取得 device.system (NEW 模式)
    fret = mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_NEW, &system_v);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-entry][NEW ] %s.date = " MCM_DTYPE_S_PF, path1, system_v.date);
    DMSG("[get-entry][NEW ] %s.ip_addr = " MCM_DTYPE_S_PF, path1, system_v.ip_addr);
    DMSG("[get-entry][NEW ] %s.uptime = " MCM_DTYPE_IULL_PF, path1, system_v.uptime);
    DMSG("[get-entry][NEW ] %s.loading = " MCM_DTYPE_FD_PF, path1, system_v.loading);
    // 範例-02c : 取得 device.system (AUTO 模式)
    fret = mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_AUTO, &system_v);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    source = fret == MCM_DACCESS_SYS ? "SYS" : "NEW";
    DMSG("[get-entry][AUTO] %s.date = " MCM_DTYPE_S_PF " [%s]",
         path1, system_v.date, source);
    DMSG("[get-entry][AUTO] %s.ip_addr = " MCM_DTYPE_S_PF " [%s]",
         path1, system_v.ip_addr, source);
    DMSG("[get-entry][AUTO] %s.uptime = " MCM_DTYPE_IULL_PF " [%s]",
         path1, system_v.uptime, source);
    DMSG("[get-entry][AUTO] %s.loading = " MCM_DTYPE_FD_PF " [%s]",
         path1, system_v.loading, source);

    path1 = "device.vap.@2.station.@1";
    // 範例-03a : 取得 device.vap.#15.station.@1 (SYS 模式)
    fret = mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_SYS, &station_v);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-entry][SYS ] %s.ekey = " MCM_DTYPE_EK_PF, path1, station_v.ekey);
    DMSG("[get-entry][SYS ] %s.mac_addr = " MCM_DTYPE_S_PF, path1, station_v.mac_addr);
    DMSG("[get-entry][SYS ] %s.rule = " MCM_DTYPE_RK_PF, path1, station_v.rule);
    // 範例-03b : 取得 device.vap.#15.station.@1 (NEW 模式)
    fret = mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_NEW, &station_v);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[get-entry][NEW ] %s.ekey = " MCM_DTYPE_EK_PF, path1, station_v.ekey);
    DMSG("[get-entry][NEW ] %s.mac_addr = " MCM_DTYPE_S_PF, path1, station_v.mac_addr);
    DMSG("[get-entry][NEW ] %s.rule = " MCM_DTYPE_RK_PF, path1, station_v.rule);
    // 範例-03c : 取得 device.vap.#15.station.@1 (AUTO 模式)
    fret = mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_AUTO, &station_v);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_alone_by_path(%s) fail", path1);
        goto FREE_01;
    }
    source = fret == MCM_DACCESS_SYS ? "SYS" : "NEW";
    DMSG("[get-entry][AUTO] %s.ekey = " MCM_DTYPE_EK_PF " [%s]",
         path1, station_v.ekey, source);
    DMSG("[get-entry][AUTO] %s.mac_addr = " MCM_DTYPE_S_PF " [%s]",
         path1, station_v.mac_addr, source);
    DMSG("[get-entry][AUTO] %s.rule = " MCM_DTYPE_RK_PF " [%s]",
         path1, station_v.rule, source);

FREE_01:
    return fret;
}

mcm_config_set_entry_by_path
將資料寫入 entry.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
full_path
目標的路徑 [詳細]
[entry 格式][index / key 模式]
MCM_DTYPE_FLAG_TD
data_access
要使用何種模式 [詳細]
void *
data_con
寫入的資料 (變數的資料型態 [詳細])
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 必須是讀寫.
02.  因為 ek 類型的 member 是唯讀的, 所以資料庫內 ek 的數值不會被寫入的資料覆蓋.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;
    struct mcm_dv_device_vap_t vap_v;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 範例-03 : 設定 device.vap.@1
    path1 = "device.vap.@1";
    memset(&vap_v, 0, sizeof(vap_v));
    snprintf(vap_v.ssid, sizeof(vap_v.ssid), "ssid-%u", rand() % 100);
    vap_v.channel = rand() % 150;
    DMSG("[set-entry] %s.ssid = " MCM_DTYPE_S_PF, path1, vap_v.ssid);
    DMSG("[set-entry] %s.channel = " MCM_DTYPE_IUI_PF, path1, vap_v.channel);
    if(mcm_lulib_set_entry(&self_lulib, path1, &vap_v, sizeof(vap_v)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_set_entry(%s) fail", path1);
        goto FREE_02;
    }

    // 範例-04 : 增加 device.vap.#23.station.#1
    path1 = "device.vap.#23.station.#1";
    DMSG("[add-entry] %s", path1);
    if(mcm_lulib_add_entry(&self_lulib, path1, NULL, NULL, 0) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_add_entry(%s) fail", path1);
        goto FREE_02;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_set_entry_value_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_set_entry_value_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1;
    struct mcm_dv_device_t device_v;
    struct mcm_dv_device_system_t system_v;
    struct mcm_dv_device_vap_t vap_v;
    struct mcm_dv_device_vap_station_t station_v;
    MCM_DTYPE_USIZE_TD i;

    srand(time(NULL));

    // 範例-01 : 設定 device (SYS 模式)
    path1 = "device";
    memset(&device_v, 0, sizeof(device_v));
    snprintf(device_v.descript, sizeof(device_v.descript), "network-device-%02u", rand() % 100);
    for(i = 0; i < sizeof(device_v.serial_number); i++)
        device_v.serial_number[i] = rand() % 256;
    DMSG("[set-entry][SYS] %s.descript = " MCM_DTYPE_S_PF, path1, device_v.descript);
    DMSG("[set-entry][SYS] %s.serial_number = "
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF
         MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF MCM_DTYPE_B_PF,
         path1,
         device_v.serial_number[0], device_v.serial_number[1], device_v.serial_number[2],
         device_v.serial_number[3], device_v.serial_number[4], device_v.serial_number[5],
         device_v.serial_number[6], device_v.serial_number[7], device_v.serial_number[8],
         device_v.serial_number[9]);
    if(mcm_config_set_entry_by_path(this_session, path1, MCM_DACCESS_SYS, &device_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-02 : 設定 device.system (NEW 模式)
    path1 = "device.system";
    memset(&system_v, 0, sizeof(system_v));
    snprintf(system_v.date, sizeof(system_v.date), "2008/01/%02u", rand() % 30);
    snprintf(system_v.ip_addr, sizeof(system_v.ip_addr), "192.168.20.%u", rand() % 250);
    system_v.uptime = rand();
    system_v.loading = ((MCM_DTYPE_FD_TD) 25000) / ((rand() % 100) + 1);
    DMSG("[set-entry][NEW] %s.date = " MCM_DTYPE_S_PF, path1, system_v.date);
    DMSG("[set-entry][NEW] %s.ip_addr = " MCM_DTYPE_S_PF, path1, system_v.ip_addr);
    DMSG("[set-entry][NEW] %s.uptime = " MCM_DTYPE_IULL_PF, path1, system_v.uptime);
    DMSG("[set-entry][NEW] %s.loading = " MCM_DTYPE_FD_PF, path1, system_v.loading);
    if(mcm_config_set_entry_by_path(this_session, path1, MCM_DACCESS_NEW, &system_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-03 : 設定 device.vap.@1 (NEW 模式)
    path1 = "device.vap.@1";
    memset(&vap_v, 0, sizeof(vap_v));
    snprintf(vap_v.ssid, sizeof(vap_v.ssid), "ssid-%u", rand() % 100);
    vap_v.channel = rand() % 200;
    DMSG("[set-entry][NEW] %s.ssid = " MCM_DTYPE_S_PF, path1, vap_v.ssid);
    DMSG("[set-entry][NEW] %s.channel = " MCM_DTYPE_IUI_PF, path1, vap_v.channel);
    if(mcm_config_set_entry_by_path(this_session, path1, MCM_DACCESS_NEW, &vap_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-04 : 設定 device.vap.#23.station.#1 (NEW 模式)
    path1 = "device.vap.#23.station.#1";
    memset(&station_v, 0, sizeof(station_v));
    snprintf(station_v.mac_addr, sizeof(station_v.mac_addr), "00:AA:CC:22:44:%02X", rand() % 255);
    station_v.rule = rand() % 50;
    DMSG("[set-entry][NEW] %s.mac_addr = " MCM_DTYPE_S_PF, path1, station_v.mac_addr);
    DMSG("[set-entry][NEW] %s.rule = " MCM_DTYPE_RK_PF, path1, station_v.rule);
    if(mcm_config_set_entry_by_path(this_session, path1, MCM_DACCESS_NEW, &station_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_set_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

mcm_config_add_entry_by_path
增加一筆 entry.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
full_path
目標的路徑 [詳細]
[entry 格式][index / key 模式]
加入的目標必須是 [key 模式]
char *
insert_path
要插入到何處的路徑 [詳細]
[index 模式] / [key 模式]
MCM_DTYPE_FLAG_TD
data_access
要使用何種模式 [詳細]
void *
data_con
寫入的資料 (變數的資料型態 [詳細])
可為 NULL, 表示使用初始值 (資料模型中設的 $(default)) [詳細]
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 必須是讀寫.
02.  路徑可以是 [indxe / key 模式], 但是最後一段要加入的目標必須是 [key 模式].
03.  增加 entry 需要指定新的 key (不可和存在的 entry 的 key 相同).
04.  key 值會使用 full_path 的值, data_con 內的 key 值會被忽略.
05.  增加多層資料時, 要逐層增加.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 範例-03 : 增加 device.vap.#200
    path1 = "device.vap.#200";
    DMSG("[add-entry] %s", path1);
    if(mcm_lulib_add_entry(&self_lulib, path1, NULL, NULL, 0) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_add_entry(%s) fail", path1);
        goto FREE_02;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_add_entry_value_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_add_entry_value_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1;
    struct mcm_dv_device_vap_station_t station_v;
    struct mcm_dv_device_limit_t limit_v;

    srand(time(NULL));

    // 範例-01 : 增加 device.vap.#100, 插入到第 1 筆 entry 之前 (@1), (SYS 模式)
    path1 = "device.vap.#100";
    DMSG("[add-entry][SYS] %s", path1);
    if(mcm_config_add_entry_by_path(this_session, path1, "@1", MCM_DACCESS_SYS, NULL)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_add_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-02 : 增加 device.vap.@1.station.#10, 放在串列尾端 (NULL), (SYS 模式)
    path1 = "device.vap.@1.station.#10";
    DMSG("[add-entry][SYS] %s", path1);
    if(mcm_config_add_entry_by_path(this_session, path1, NULL, MCM_DACCESS_SYS, NULL)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_add_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-04 : 增加 device.vap.#200.station.#10, 放在串列尾端 (""), (NEW 模式)
    path1 = "device.vap.#200.station.#10";
    memset(&station_v, 0, sizeof(station_v));
    snprintf(station_v.mac_addr, sizeof(station_v.mac_addr), "00:1a:2b:c3:4d:%02X", rand() % 255);
    station_v.rule = rand() % 50;
    DMSG("[add-entry][NEW] %s.mac_addr = " MCM_DTYPE_S_PF, path1, station_v.mac_addr);
    DMSG("[add-entry][NEW] %s.rule = " MCM_DTYPE_RK_PF, path1, station_v.rule);
    if(mcm_config_add_entry_by_path(this_session, path1, "", MCM_DACCESS_NEW, &station_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_add_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-05 : 增加 device.limit.#50, 插入到 key 為 6 的 entry 之前 (#6), (NEW 模式)
    path1 = "device.limit.#50";
    memset(&limit_v, 0, sizeof(limit_v));
    snprintf(limit_v.name, sizeof(limit_v.name), "rule-%u", rand() % 100);
    limit_v.priority = rand() % 100;
    DMSG("[add-entry][NEW] %s.name = " MCM_DTYPE_S_PF, path1, limit_v.name);
    DMSG("[add-entry][NEW] %s.priority = " MCM_DTYPE_ISI_PF, path1, limit_v.priority);
    if(mcm_config_add_entry_by_path(this_session, path1, "#6", MCM_DACCESS_NEW, &limit_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_add_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

mcm_config_del_entry_by_path
刪除一筆 entry.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
full_path
目標的路徑 [詳細]
[entry 格式][index / key 模式]
MCM_DTYPE_FLAG_TD
data_access
要使用何種模式 [詳細]
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 必須是讀寫.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_del_entry_value_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_del_entry_value_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1;

    srand(time(NULL));

    // 範例-01 : 刪除 device.vap.@1 (SYS 模式)
    path1 = "device.vap.@1";
    DMSG("[del-entry][SYS] %s", path1);
    if(mcm_config_del_entry_by_path(this_session, path1, MCM_DACCESS_SYS) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_del_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-02 : 刪除 device.vap.#15.station.#33 (NEW 模式)
    path1 = "device.vap.#15.station.#33";
    DMSG("[del-entry][NEW] %s", path1);
    if(mcm_config_del_entry_by_path(this_session, path1, MCM_DACCESS_NEW) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_del_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

mcm_config_get_all_key_by_path
讀出所有 entry 的 key 值.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
mix_path
目標的路徑 [詳細]
[index / key 模式]
MCM_DTYPE_EK_TD **
key_buf
紀錄 key 列表的變數的緩衝
內部函式會配置記憶體空間並放入資料, 使用完需要釋放, 傳入參數需要做強制轉型 (MCM_DTYPE_EK_TD **)
MCM_DTYPE_EK_TD *
count_buf
紀錄資料筆數的緩衝
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 可以是唯讀或讀寫.
02.  使用 index 模式和 key 模式的資料搜索的速度 :
A.  知道所有 entry 的 key 值, 使用 key 模式的路徑.
B.  不知道所有 entry 的 key 值, 先使用此函式取得所有 entry 的 key 值, 再使用 key 模式的路徑.
C.  不知道所有 entry 的 key 值, 使用 index 模式的路徑.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_all_key_value_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_all_key_value_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1, path2[MCM_PATH_MAX_LENGTH], *source;
    struct mcm_dv_device_vap_t vap_v;
    struct mcm_dv_device_vap_station_t station_v;
    MCM_DTYPE_EK_TD i, count, *key_array;


    // 範例-01 : 取得 device.vap.* 的所有 key.
    path1 = "device.vap.*";
    if(mcm_config_get_all_key_by_path(this_session, path1, (MCM_DTYPE_EK_TD **) &key_array,
                                      &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_add_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[count] %s = " MCM_DTYPE_EK_PF, path1, count);
    // 接著使用 key 值取得所有的 device.vap.*
    for(i = 0; i < count; i++)
    {
        snprintf(path2, sizeof(path2), "device.vap.#%u", key_array[i]);
        fret = mcm_config_get_entry_by_path(this_session, path2, MCM_DACCESS_AUTO, &vap_v);
        if(fret < MCM_RCODE_PASS)
        {
            DMSG("call mcm_config_get_entry_by_path(%s) fail", path2);
            goto FREE_01;
        }
        source = fret == MCM_DACCESS_SYS ? "SYS" : "NEW";
        DMSG("[get-entry][AUTO] %s.ssid = " MCM_DTYPE_S_PF " [%s]", path2, vap_v.ssid, source);
        DMSG("[get-entry][AUTO] %s.channel = " MCM_DTYPE_IUI_PF " [%s]",
             path2, vap_v.channel, source);
    }
    free(key_array);

    // 範例-02 : 取得 device.vap.@1.station.* 所有的 key.
    path1 = "device.vap.@1.station.*";
    if(mcm_config_get_all_key_by_path(this_session, path1, (MCM_DTYPE_EK_TD **) &key_array,
                                      &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_add_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[count] %s = " MCM_DTYPE_EK_PF, path1, count);
    // 接著使用 key 值取得所有的 device.vap.@1.station.*
    for(i = 0; i < count; i++)
    {
        snprintf(path2, sizeof(path2), "device.vap.@1.station.#%u", key_array[i]);
        if(mcm_config_get_entry_by_path(this_session, path2, MCM_DACCESS_AUTO, &station_v)
                                        < MCM_RCODE_PASS)
        {
            DMSG("call mcm_config_get_entry_by_path(%s) fail", path2);
            goto FREE_01;
        }
        source = fret == MCM_DACCESS_SYS ? "SYS" : "NEW";
        DMSG("[get-entry][AUTO] %s.ekey = " MCM_DTYPE_EK_PF " [%s]",
             path2, station_v.ekey, source);
        DMSG("[get-entry][AUTO] %s.mac_addr = " MCM_DTYPE_S_PF " [%s]",
             path2, station_v.mac_addr, source);
        DMSG("[get-entry][AUTO] %s.rule = " MCM_DTYPE_RK_PF " [%s]",
             path2, station_v.rule, source);
    }
    free(key_array);

    // 範例-03 : 取得 device.vap.#2.station.* 所有的 key.
    path1 = "device.vap.#2.station.*";
    if(mcm_config_get_all_key_by_path(this_session, path1, (MCM_DTYPE_EK_TD **) &key_array,
                                      &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_add_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("[count] %s = " MCM_DTYPE_EK_PF, path1, count);
    // 接著使用 key 值取得所有的 device.vap.@1.station.*
    for(i = 0; i < count; i++)
    {
        snprintf(path2, sizeof(path2), "device.vap.#2.station.#%u", key_array[i]);
        if(mcm_config_get_entry_by_path(this_session, path2, MCM_DACCESS_AUTO, &station_v)
                                        < MCM_RCODE_PASS)
        {
            DMSG("call mcm_config_get_entry_by_path(%s) fail", path2);
            goto FREE_01;
        }
        source = fret == MCM_DACCESS_SYS ? "SYS" : "NEW";
        DMSG("[get-entry][AUTO] %s.ekey = " MCM_DTYPE_EK_PF " [%s]",
             path2, station_v.ekey, source);
        DMSG("[get-entry][AUTO] %s.mac_addr = " MCM_DTYPE_S_PF " [%s]",
             path2, station_v.mac_addr, source);
        DMSG("[get-entry][AUTO] %s.rule = " MCM_DTYPE_RK_PF " [%s]",
             path2, station_v.rule, source);
    }
    free(key_array);

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

mcm_config_get_all_entry_by_path
讀出所有 entry 的資料.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
mix_path
目標的路徑 [詳細]
[index / key 模式]
MCM_DTYPE_FLAG_TD
data_access
要使用何種模式 [詳細]
MCM_DTYPE_EK_TD **
data_buf
紀錄資料的數值的變數的緩衝
內部函式會配置記憶體空間並放入資料, 使用完需要釋放, 傳入參數需要做強制轉型 (void **)
MCM_DTYPE_FLAG_TD **
source_buf
紀錄資料的來源的的變數緩衝 (MCM_DACCESS_SYS 或 MCM_DACCESS_NEW)
可為 NULL, 表示不記錄資料的來源
內部函式會配置記憶體空間並放入資料, 使用完需要釋放, 傳入參數需要做強制轉型 (MCM_DTYPE_FLAG_TD **)
MCM_DTYPE_EK_TD *
count_buf
紀錄資料筆數的緩衝
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
如果 data_access 指定 MCM_DACCESS_SYS 或 MCM_DACCESS_NEW, 但是目標的所有 entry 中只要有一個 entry 不符合, 也會回傳錯誤
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 可以是唯讀或讀寫.

範例-01 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;
    struct mcm_dv_device_vap_t vap_v;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 範例-01 : 設定 device.vap.@1
    path1 = "device.vap.@1";
    memset(&vap_v, 0, sizeof(vap_v));
    snprintf(vap_v.ssid, sizeof(vap_v.ssid), "ssid-%u", rand() % 100);
    vap_v.channel = rand() % 150;
    DMSG("[set-entry] %s.ssid = " MCM_DTYPE_S_PF, path1, vap_v.ssid);
    DMSG("[set-entry] %s.channel = " MCM_DTYPE_IUI_PF, path1, vap_v.channel);
    if(mcm_lulib_set_entry(&self_lulib, path1, &vap_v, sizeof(vap_v)) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_set_entry(%s) fail", path1);
        goto FREE_02;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_all_entry_value_test_01";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_all_entry_value_test_01(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1, path2[MCM_PATH_MAX_LENGTH], *source;
    struct mcm_dv_device_vap_t *vap_v;
    struct mcm_dv_device_vap_station_t *station_v;
    MCM_DTYPE_FLAG_TD *from;
    MCM_DTYPE_EK_TD i, count;

    // 範例-01 : 取得 device.vap.* 的所有 entry 資料 (AUTO 模式).
    path1 = "device.vap.*";
    if(mcm_config_get_all_entry_by_path(this_session, path1, MCM_DACCESS_AUTO, (void **) &vap_v,
                                        (MCM_DTYPE_FLAG_TD **) &from, &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_all_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }
    for(i = 0; i < count; i++)
    {
        snprintf(path2, sizeof(path2), "device.vap.@%u", i + 1);
        source = from[i] == MCM_DACCESS_NEW ? "NEW" : "SYS";
        DMSG("[get-all-entry][AUTO] %s.ekey = " MCM_DTYPE_EK_PF " [%s]",
             path2, vap_v[i].ekey, source);
        DMSG("[get-all-entry][AUTO] %s.ssid = " MCM_DTYPE_S_PF " [%s]",
             path2, vap_v[i].ssid, source);
        DMSG("[get-all-entry][AUTO] %s.channel = " MCM_DTYPE_IUI_PF " [%s]",
             path2, vap_v[i].channel, source);
    }
    free(vap_v);
    free(from);

    // 範例-02 : 取得 device.vap.#15.station.* 的所有 entry 資料 (SYS 模式).
    path1 = "device.vap.#15.station.*";
    if(mcm_config_get_all_entry_by_path(this_session, path1, MCM_DACCESS_SYS,
                                        (void **) &station_v, (MCM_DTYPE_FLAG_TD **) &from,
                                        &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_all_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }
    for(i = 0; i < count; i++)
    {
        snprintf(path2, sizeof(path2), "device.vap.#15.station.@%u", i + 1);
        source = from[i] == MCM_DACCESS_NEW ? "NWE" : "SYS";
        DMSG("[get-all-entry][SYS ] %s.ekey = " MCM_DTYPE_EK_PF " [%s]",
             path1, station_v[i].ekey, source);
        DMSG("[get-all-entry][SYS ] %s.mac_addr = " MCM_DTYPE_S_PF " [%s]",
             path1, station_v[i].mac_addr, source);
        DMSG("[get-all-entry][SYS ] %s.rule = " MCM_DTYPE_RK_PF " [%s]",
             path1, station_v[i].rule, source);
    }
    free(station_v);
    free(from);

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


範例-02 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 範例-01 : 增加 device.limit.#65
    path1 = "device.limit.#65";
    DMSG("[add-entry] %s", path1);
    if(mcm_lulib_add_entry(&self_lulib, path1, NULL, NULL, 0) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_add_entry(%s) fail", path1);
        goto FREE_02;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_all_entry_value_test_02";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_all_entry_value_test_02(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1, path2[MCM_PATH_MAX_LENGTH], *source;
    struct mcm_dv_device_limit_t *limit_v;
    MCM_DTYPE_FLAG_TD *from;
    MCM_DTYPE_EK_TD i, count;

    // 範例-01 : 取得 device.limit.* 的所有 entry 資料 (SYS 模式).
    // 因為最後一筆 device.limit 是新加入的, 系統資料區並沒有資料所以會找不到,
    // 而只要有一筆資料不符合 (使用 SYS 模式但是系統資料區沒有資料) 就會回傳錯誤.
    path1 = "device.limit.*";
    if(mcm_config_get_all_entry_by_path(this_session, path1, MCM_DACCESS_SYS, (void **) &limit_v,
                                        (MCM_DTYPE_FLAG_TD **) &from, &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_all_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }
    for(i = 0; i < count; i++)
    {
        snprintf(path2, sizeof(path2), "device.limit.@%u", i + 1);
        source = from[i] == MCM_DACCESS_NEW ? "NEW" : "SYS";
        DMSG("[get-all-entry][SYS ] %s.ekey = " MCM_DTYPE_EK_PF " [%s]",
             path2, limit_v[i].ekey, source);
        DMSG("[get-all-entry][SYS ] %s.name = " MCM_DTYPE_S_PF " [%s]",
             path2, limit_v[i].name, source);
        DMSG("[get-all-entry][SYS ] %s.priority = " MCM_DTYPE_ISI_PF " [%s]",
             path2, limit_v[i].priority, source);
    }
    free(limit_v);
    free(from);

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


範例-03 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RO;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_all_entry_value_test_03";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_all_entry_value_test_03(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1, path2[MCM_PATH_MAX_LENGTH], *source;
    struct mcm_dv_device_limit_t *limit_v;
    MCM_DTYPE_FLAG_TD *from;
    MCM_DTYPE_EK_TD i, count;

    // 範例-01 : 取得 device.limit.* 的所有 entry 資料 (NEW 模式).
    // 因為外部程式沒有做修改 (設定/增加/刪除) 的動作, 所以新進資料區沒有資料,
    // 而只要有一筆資料不符合 (使用 NEW 模式但是新進資料區沒有資料) 就會回傳錯誤.
    path1 = "device.limit.*";
    if(mcm_config_get_all_entry_by_path(this_session, path1, MCM_DACCESS_NEW, (void **) &limit_v,
                                        (MCM_DTYPE_FLAG_TD **) &from, &count) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_all_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }
    for(i = 0; i < count; i++)
    {
        snprintf(path2, sizeof(path2), "device.limit.@%u", i + 1);
        source = from[i] == MCM_DACCESS_NEW ? "NEW" : "SYS";
        DMSG("[get-all-entry][SYS ] %s.ekey = " MCM_DTYPE_EK_PF " [%s]",
             path2, limit_v[i].ekey, source);
        DMSG("[get-all-entry][SYS ] %s.name = " MCM_DTYPE_S_PF " [%s]",
             path2, limit_v[i].name, source);
        DMSG("[get-all-entry][SYS ] %s.priority = " MCM_DTYPE_ISI_PF " [%s]",
             path2, limit_v[i].priority, source);
    }
    free(limit_v);
    free(from);

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

mcm_config_del_all_entry_by_path
刪除所有 entry.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
mix_path
目標的路徑 [詳細]
[index / key 模式]
MCM_DTYPE_FLAG_TD
data_access
要使用何種模式 [詳細]
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 必須是讀寫.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RW;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_del_all_entry_value_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_del_all_entry_value_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1;

    srand(time(NULL));

    // 範例-01 : 刪除 device.vap.@1.* (SYS 模式)
    path1 = "device.vap.@1.station.*";
    DMSG("[del-all-entry][SYS] %s", path1);
    if(mcm_config_del_all_entry_by_path(this_session, path1, MCM_DACCESS_SYS) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_del_all_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-02 : 刪除 device.vap.#15.* (NEW 模式)
    path1 = "device.vap.#15.station.*";
    DMSG("[del-all-entry][NEW] %s", path1);
    if(mcm_config_del_all_entry_by_path(this_session, path1, MCM_DACCESS_NEW) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_del_all_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    // 範例-03 : 刪除 device.limit.* (NEW 模式)
    path1 = "device.limit.*";
    DMSG("[del-all-entry][NEW] %s", path1);
    if(mcm_config_del_all_entry_by_path(this_session, path1, MCM_DACCESS_NEW) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_del_all_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

mcm_config_get_usable_key_by_path
取得可用的 key.
參數 說明
struct mcm_service_session_t *
this_session
請求端的連線資訊
char *
mix_path
目標的路徑 [詳細]
[index / key 模式]
MCM_DTYPE_EK_TD *
key_buf
紀錄可用的 key 的緩衝
回傳 說明
>= MCM_RCODE_PASS 成功
 < MCM_RCODE_PASS
(MCM_RCODE_CONFIG_NOT_FIND_STORE)
錯誤, 目標 entry 不存在
 < MCM_RCODE_PASS
(other)
錯誤, 其他錯誤

注意事項 :
01.  外部程式或網頁程式的資料存取模式 (session_permission) 可以是唯讀或讀寫.
02.  key_buf 返回的值大於 0 才表示有可用的 key.

範例 :
外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RO;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 呼叫內部模組.
    path1 = "mcm_module_get_usable_key_test";
    DMSG("[run] %s", path1);
    if(mcm_lulib_run(&self_lulib, path1, NULL, 0, NULL, NULL) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_get_usable_key_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1;
    MCM_DTYPE_EK_TD key;

    // 範例-01 : 取得 device.vap.* 可用的 key
    path1 = "device.vap.*";
    if(mcm_config_get_usable_key_by_path(this_session, path1, &key) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_usable_key_by_path(%s) fail", path1);
        goto FREE_01;
    }
    if(key == 0)
    {
        DMSG("[usable-key] %s = entry is full", path1, key);
    }
    else
    {
        DMSG("[usable-key] %s = " MCM_DTYPE_EK_PF, path1, key);
    }

    // 範例-02 : 取得 device.vap.#15.station.* 可用的 key
    path1 = "device.vap.#15.station.*";
    if(mcm_config_get_usable_key_by_path(this_session, path1, &key) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_usable_key_by_path(%s) fail", path1);
        goto FREE_01;
    }
    if(key == 0)
    {
        DMSG("[usable-key] %s = entry is full", path1, key);
    }
    else
    {
        DMSG("[usable-key] %s = " MCM_DTYPE_EK_PF, path1, key);
    }

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


範例程式的使用

01.  範例程式目錄在 mint_cm/usage/example/0403.


02.  下面關於 make 的操作沒有特別註明的話都是在 mint_cm 目錄.


03.  第一次使用, 使用 make example_add KEY=0403 載入範例並編譯.


04.  web_app 是範例程式.

範例項目 :
case-01 測試項目
mcm_config_get_max_count_by_path
case-02 測試項目
mcm_config_get_count_by_path
case-03 測試項目
mcm_config_get_alone_by_path
case-04 測試項目
mcm_config_get_all_key_by_path
mcm_config_get_entry_by_path
case-05 測試項目
mcm_config_get_all_entry_by_path
case-06 測試項目
mcm_config_set_alone_by_path
mcm_config_set_entry_by_path
case-07 測試項目
mcm_config_del_entry_by_path
mcm_config_get_usable_key_by_path
mcm_config_add_entry_by_path
case-08 測試項目
mcm_config_del_all_entry_by_path
mcm_config_add_entry_by_path


05.  先執行 mcm_daemon 和 mini_httpd 才可測試.


06.  瀏覽器連至 http://<server-address>/web_app_0403_index.html 就可以看到範例頁面.


07.  測試完畢不使用後, 使用 make example_del KEY=0403 將範例移除.


08.  範例程式目錄下的檔案在做完 make example_add 後會複製到真正使用的位置, 要修改做測試的話要改在複製後的.
來源 profile/mcm_data_profile_0403.xml
目地 mint_cm/mcm_build/mcm_data_profile.xml
資料模型範例
有修改要使用 make all 重新編譯
來源 profile/mcm_store_profile_default_0403.txt
目地 mint_cm/mcm_build/mcm_store_profile_default.txt
資料預設值範例
使用 make all 後會再複製到 mint_cm/run
來源 web_app
目地 mint_cm/run/web
網頁程式範例
來源 module/mcm_module_0403.c
目地 mint_cm/mcm_daemon/mcm_module
內部模組範例
有修改要使用 make all 重新編譯