chapter 03-04

資料的存取 (網頁端程式-基本)

此章節說明網頁程式如何透過提供的介面存取資料.


網頁的編碼格式必須是 UTF-8, 如下的宣告 :
<meta http-equiv="content-type" content="text/html; charset=utf-8">


需要的 JS 檔 :
jquery_main.js
json3.js
mcm_jslib_api.js
mcm_jslib_data_info_auto.js


CGI 的標準輸出會被重定向, 顯示錯誤訊息或除錯訊息需要直接寫入 console 設備, 需要指定 console 設備 :
mint_cm/mcm_lib/mcm_lheader/mcm_debug.h
#define MCM_DBG_CONSOLE "/dev/tty"
console 設備的路徑, 大部分是 /dev/tty 或 /dev/ttyS0 或 /dev/console

如果不支援 console 設備, 必須把顯示訊息關閉, 將以下的值設 0 關閉 :

#define MCM_CGIEMODE 1
是否顯示錯誤訊息 (mcm_cgi_config.c 和 mcm_cgi_upload.c 部分)

#define MCM_CGIECTMODE 1
是否顯示錯誤訊息 (mcm_cgi_config.c 和 mcm_cgi_upload.c 部分, 針對函示回傳錯誤時的函式呼叫流程追蹤)

#define MCM_CCDMODE 0
是否顯示除錯訊息 (mcm_cgi_config.c 部分)

#define MCM_CUDMODE 0
是否顯示除錯訊息 (mcm_cgi_upload.c 部分)

#define MCM_CCMEMODE 1
是否顯示錯誤訊息 (mcm_cgi_config_module 部分)

#define MCM_CCMDMODE 0
是否顯示除錯訊息 (mcm_cgi_config_module 部分)

#define MCM_CUMEMODE 1
是否顯示錯誤訊息 (mcm_cgi_upload_module 部分)

#define MCM_CUMDMODE 0
是否顯示除錯訊息 (mcm_cgi_upload_module 部分)


CGI 部分預設是使用靜態連結的方式使用 MintCM 函式庫, 實際使用可以改用動態連結的方式.
USE_STATIC_MCM_LIB
(mint_cm/Makefile)
YES 使用靜態鏈結
NO 使用動態鏈結


變數格式的說明

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


[mcm_jslib_lib_t this_jslib]
用來儲存相關的的資訊.
會用到的結構成員 :
[socket_path]
伺服器的位址路徑. [詳細]
[session_permission]
表示資料存取的模式.
mcm_session_permission
(mint_cm/mcm_lib/mcm_jslib/mcm_jslib_api.js)
mcm_session_permission.ro 唯讀
mcm_session_permission.rw 讀寫
如果只要讀取資料, 使用 mcm_session_permission.ro, 如果要修改 (設定/增加/刪除) 資料, 使用 mcm_session_permission.rw.
[session_stack_size]
伺服器端負責此連線的執行緒的堆疊大小. [詳細]
[request_command]
要傳送的指令串.
[data_format]
回傳的資料的格式, 指定資料要用 整數/浮點數/字串 格式輸出, 或是用字串格式輸出.
可指定的格式 :
mcm_data_format
(mint_cm/mcm_lib/mcm_jslib/mcm_jslib_api.js)
mcm_data_format.all_default 所有類型資料都使用原始 (整數/浮點數/字串) 格式輸出
mcm_data_format.ek_string ek 類型的資料使用字串格式輸出
mcm_data_format.rk_string rk 類型的資料使用字串格式輸出
mcm_data_format.isc_string isc 類型的資料使用字串格式輸出
mcm_data_format.iuc_string iuc 類型的資料使用字串格式輸出
mcm_data_format.iss_string iss 類型的資料使用字串格式輸出
mcm_data_format.ius_string ius 類型的資料使用字串格式輸出
mcm_data_format.isi_string isi 類型的資料使用字串格式輸出
mcm_data_format.iui_string iui 類型的資料使用字串格式輸出
mcm_data_format.isll_string isll 類型的資料使用字串格式輸出
mcm_data_format.iull_string iull 類型的資料使用字串格式輸出
mcm_data_format.ff_string ff 類型的資料使用字串格式輸出
mcm_data_format.fd_string fd 類型的資料使用字串格式輸出
mcm_data_format.fld_string fld 類型的資料使用字串格式輸出
mcm_data_format.all_string 所有類型資料都使用字串格式輸出
如果要指定多種類型的資料使用字串格式輸出, 使用 OR 運算疊加.

JavaScript 使用 IEEE-754 (雙精度) 來記錄數字資料, 小數的精確值是 52 位元 (紀錄整數部分), isll 和 iull 的原型是 long long 類型, 在一般系統是 64 位元, 超過 JavaScript 能記錄的上限, 如果有使用 isll 或 iull 類型的資料而且數值大小會超過 52 位元的話, 必須改用字串格式輸出
[after_complete]
CGI 端處理完後預設要如何回應 (回傳訊息).
mcm_after_complete
(mint_cm/mcm_lib/mcm_jslib/mcm_jslib_api.js)
mcm_after_complete.none 不回傳任何訊息
mcm_after_complete.reload 回傳重新載入頁面的訊息
必須使用 mcm_jslib_run_script() 執行回傳的訊息
[other_query]
額外的查詢參數, 不需要使用的話填入空字串.


mask_path
[詳細]
用途 :
01.  取得資料筆數上限, 也就是資料模型中的 $(max) 值.
02.  讀出資料. (get)


mix_path
[詳細]
在網頁端使用只能使用 [key 模式].
用途 :
01.  刪除資料. (delall)


full_path
[詳細]
在網頁端使用只能使用 [key 模式].
用途 :
01.  寫入資料. (set)
02.  增加資料. (add)
03.  刪除資料. (del)


insert_path
[詳細]
在網頁端使用只能使用 [key 模式].
用途 :
01.  增加資料時指定要插入到哪個 entry 之前. (add)


網頁程式要存取資料庫時, 要將需求組合成一條條的指令送給 mcm_cgi_config 處理.


使用的函式

mcm_jslib_convert_html_str
要將字串資料使用動態產生網頁元素的方式顯示時 (document.write, innerHTML, ...), 需要注意特殊字元 ["] [&] [<] [>] [ ], 透過此函式將特殊字元做轉換.
參數 說明
data_con 要轉換的字串
回傳
轉換後的字串

mcm_jslib_convert_submit_str
要將字串資料寫入資料庫時, 需要將特殊字元轉換成 %$(HEX) 格式, 透過此函式做轉換.
參數 說明
data_con 要轉換的字串
回傳
轉換後的字串

mcm_jslib_run_script
執行指令後, 回應的訊息可以是 JavaScript 格式, 使用此函式執行.
參數 說明
script_con 要執行的 JavaScript 內容

mcm_jslib_obtain_max_count
要求取得最大資料筆數限制.
參數 說明
this_jslib 用來儲存相關的的資訊
需要先設定以下的結構成員 :
socket_path [詳細]
session_permission [詳細]
session_stack_size [詳細]
request_command [詳細]
other_query [詳細]
回傳 說明
$.rep_code 指令結果 >= mcm_return_code.pass 成功
 < mcm_return_code.pass 錯誤
$.rep_data 如果指令結果是成功 :
JSON 格式的實際資料, 需要使用 JSON.parse() 轉換
如果指令結果是錯誤 :
JavaScript 格式的錯誤訊息, 需要使用 mcm_jslib_run_script() 執行

mcm_jslib_obtain_config
要求取得資料.
參數 說明
this_jslib 用來儲存相關的的資訊
需要先設定以下的結構成員 :
socket_path [詳細]
session_permission [詳細]
session_stack_size [詳細]
request_command [詳細]
data_format [詳細]
other_query [詳細]
回傳 說明
$.rep_code 指令結果 >= mcm_return_code.pass 成功
 < mcm_return_code.pass 錯誤
$.rep_data 如果指令結果是成功 :
JSON 格式的實際資料, 需要使用 JSON.parse() 轉換
如果指令結果是錯誤 :
自定格式的錯誤訊息 (訊息的撰寫參考 #05-04#)

mcm_jslib_submit_config
要求設定資料.
參數 說明
this_jslib 用來儲存相關的的資訊
需要先設定以下的結構成員 :
socket_path [詳細]
session_permission [詳細]
session_stack_size [詳細]
request_command [詳細]
after_complete [詳細]
other_query [詳細]
回傳 說明
$.rep_code 指令結果 >= mcm_return_code.pass 成功
 < mcm_return_code.pass 錯誤
$.rep_data 自定格式的訊息 (訊息的撰寫參考 #05-04#)


指令的格式

根據使用的功能說明指令的格式和用法.

取得資料筆數上限, 也就是資料模型中的 $(max) 值

格式 :
"&get.$(mask_path)"

$(mask_path) 目標的路徑 [詳細]

注意事項 :
01.  資料存取模式可以是 mcm_session_permission.ro 或 mcm_session_permission.rw.
02.  得到的資料是 JSON 格式.
03.  得到的數值是整數格式.

建立指令.
範例 :
var req_cmd = "";

// 取得 device.system 的資料筆數上限.
req_cmd += "&get.device.system";

// 取得 device.vap.* 的資料筆數上限.
req_cmd += "&get.device.vap.*";

// 取得 device.vap.*.station.* 的資料筆數上限.
req_cmd += "&get.device.vap.*.station.*";


之後使用 mcm_jslib_obtain_max_count() 送出請求.
範例 :
var self_jslib, rep_ret;

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.ro;
self_jslib.session_stack_size = 0;
self_jslib.request_command = req_cmd;
self_jslib.other_query = "";
rep_ret = mcm_jslib_obtain_max_count(self_jslib);


之後檢查返回的結果, 返回成功的話, 使用 JSON.parse() 將回傳的資料轉為 JSON 格式才可使用.
範例 :
var mcm_dv;

if(rep_ret.rep_code < mcm_return_code.pass)
{
    alert("call mcm_jslib_obtain_max_count() fail" +
          "[" + rep_ret.rep_code + "]");
    mcm_jslib_run_script(rep_ret.rep_data);
    return;
}
mcm_dv = JSON.parse(rep_ret.rep_data);


紀錄最大資料數目限制的變數名稱是 $max_count
範例 :
// device.system 的資料筆數上限.
console.log("[max-count] device.system = ",
            mcm_dv.device.system.$max_count);

// device.vap.* 的資料筆數上限.
console.log("[max-count] device.vap.* = ",
            mcm_dv.device.vap.$max_count);

// device.vap.*.station.* 的資料筆數上限.
console.log("[max-count] device.vap.*.station.* = ",
            mcm_dv.device.vap.station.$max_count);


完整程式 :
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
function main_init()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    req_cmd = "&get.device.system" +
              "&get.device.vap.*" +
              "&get.device.vap.*.station.*";

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.ro;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_obtain_max_count(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_obtain_max_count() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_dv = JSON.parse(rep_ret.rep_data);

    console.log("[max-count] device.system = ",
                mcm_dv.device.system.$max_count);
    console.log("[max-count] device.vap.* = ",
                mcm_dv.device.vap.$max_count);
    console.log("[max-count] device.vap.*.station.* = ",
                mcm_dv.device.vap.station.$max_count);
}
</script>
</head>
<body>
  <button type="button" onclick="main_init()">test</button>
</body>
</html>


除了上述方式外, 可以使用另一種方式取得 group 的資料筆數限制.
必須先寫好資料模型檔並編譯完成, mint_cm/mcm_lib/mcm_jslib/mcm_jslib_data_info_auto.js 會產生對應的資料變數.

#02-02# 的資料模型為例, 會產生 :
// device
var mcm_mcount_device_max_count = 1;

// device.system
var mcm_mcount_device_system_max_count = 1;

// device.vap.*
var mcm_mcount_device_vap_max_count = 16;

// device.vap.*.extra
var mcm_mcount_device_vap_extra_max_count = 1;

// device.vap.*.station.*
var mcm_mcount_device_vap_station_max_count = 32;

// device.limit.*
var mcm_mcount_device_limit_max_count = 64;

// device.client.*
var mcm_mcount_device_client_max_count = 128;

變數內的值就是實際的 $(max) 值.

範例 :
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
function main_init()
{
    // device.system 的資料筆數上限.
    console.log("[max-count] device.system = ",
                mcm_mcount_device_system_max_count);

    // device.vap.* 的資料筆數上限.
    console.log("[max-count] device.vap.* = ",
                mcm_mcount_device_vap_max_count);

    // device.vap.*.station.* 的資料筆數上限.
    console.log("[max-count] device.vap.*.station.* = ",
                mcm_mcount_device_vap_station_max_count);
}
</script>
</head>
<body>
  <button type="button" onclick="main_init()">test</button>
</body>
</html>

讀出資料 (get)

格式 :
"&get.$(mask_path)"

$(mask_path) 目標的路徑 [詳細]

注意事項 :
01.  資料存取模式可以是 mcm_session_permission.ro 或 mcm_session_permission.rw.
02.  只會讀出目標本身的資料, 不會讀出 child-group 的資料.
03.  會讀出目標的全部資料, 無法指定只讀出某筆資料.
04.  得到的資料是 JSON 格式.

建立指令.
範例 :
var req_cmd = "";

// 讀出 device
req_cmd += "&get.device";

// 讀出 device.system
req_cmd += "&get.device.system";

// 讀出 device.vap.*
req_cmd += "&get.device.vap.*";

// 讀出 device.vap.*.extra
req_cmd += "&get.device.vap.*.extra";

// 讀出 device.vap.*.station.*
req_cmd += "&get.device.vap.*.station.*";

// 讀出 device.limit.*
req_cmd += "&get.device.limit.*";


之後使用 mcm_jslib_obtain_config() 送出請求.
範例 :
var self_jslib, rep_ret;

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.ro;
self_jslib.session_stack_size = 0;
self_jslib.request_command = req_cmd;
self_jslib.data_format = mcm_data_format.all_default;
self_jslib.other_query = "";
rep_ret = mcm_jslib_obtain_config(self_jslib);


之後檢查返回的結果, 返回成功的話, 使用 JSON.parse() 將回傳的資料轉為 JSON 格式才可使用.
範例 :
var mcm_dv;

if(rep_ret.rep_code < mcm_return_code.pass)
{
    alert("call mcm_jslib_obtain_config() fail" +
          "[" + rep_ret.rep_code + "]");
    mcm_jslib_run_script(rep_ret.rep_data);
    return;
}
mcm_dv = JSON.parse(rep_ret.rep_data);


如果要取得目前的資料筆數, 可以使用 length 此方法.
範例 :
// device.vap.* 的資料筆數.
console.log("[count] device.vap.* = ",
            mcm_dv.device.vap.length);

// device.vap.@2 的 station 的資料筆數.
console.log("[count] device.vap.@2.station = ",
            mcm_dv.device.vap[1].station.length);

// device.limit.* 的資料筆數.
console.log("[count] device.limit.* = ",
            mcm_dv.device.vap.length);


實際的資料使用階層方式取得.
範例 :
// device 的資料.
console.log("[get] device.descript = ", 
            mcm_dv.device.descript);
console.log("[get] device.serial_number = ", 
            mcm_dv.device.serial_number);

// device.system 的資料.
console.log("[get] device.system.date = ", 
            mcm_dv.device.system.date);
console.log("[get] device.system.ip_addr = ", 
            mcm_dv.device.system.ip_addr);
console.log("[get] device.system.uptime = ", 
            mcm_dv.device.system.uptime);
console.log("[get] device.system.loading = ", 
            mcm_dv.device.system.loading);

// device.vap.@3 的資料.
console.log("[get] device.vap.@3.ekey = ",
            mcm_dv.device.vap[2].ekey);
console.log("[get] device.vap.@3.ssid = ",
            mcm_dv.device.vap[2].ssid);
console.log("[get] device.vap.@3.channel = ",
            mcm_dv.device.vap[2].channel);

// device.vap.@1.extra 的資料.
console.log("[get] device.vap.@1.extra.hidden = ",
            mcm_dv.device.vap[0].extra.hidden);
console.log("[get] device.vap.@1.extra.tx_power = ",
            mcm_dv.device.vap[0].extra.tx_power);

// device.vap.@2.station.@1 的資料.
console.log("[get] device.vap.@2.station.@1.ekey = ",
            mcm_dv.device.vap[1].station[0].ekey);
console.log("[get] device.vap.@2.station.@1.mac_addr = ",
            mcm_dv.device.vap[1].station[0].mac_addr);
console.log("[get] device.vap.@2.station.@1.rule = ",
            mcm_dv.device.vap[1].station[0].rule);

// device.limit.@1 的資料.
console.log("[get] device.limit.@1.ekey = ",
            mcm_dv.device.limit[0].ekey);
console.log("[get] device.limit.@1.name = ",
            mcm_dv.device.limit[0].name);
console.log("[get] device.limit.@1.priority = ",
            mcm_dv.device.limit[0].priority);


完整程式 :
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
function main_init()
{
    var self_jslib, req_cmd, mcm_dv;

    req_cmd = "&get.device" +
              "&get.device.system" +
              "&get.device.vap.*" +
              "&get.device.vap.*.extra" +
              "&get.device.vap.*.station.*" +
              "&get.device.limit.*";

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.ro;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    self_jslib.data_format = mcm_data_format.all_default;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_obtain_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_obtain_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_dv = JSON.parse(rep_ret.rep_data);

    console.log("[count] device.vap.* = ", 
                mcm_dv.device.vap.length);
    console.log("[count] device.vap.@2.station.* = ", 
                mcm_dv.device.vap[1].station.length);
    console.log("[count] device.limit.* = ", 
                mcm_dv.device.limit.length);

    console.log("[get] device.descript = ", 
                mcm_dv.device.descript);
    console.log("[get] device.serial_number = ", 
                mcm_dv.device.serial_number);

    console.log("[get] device.system.date = ", 
                mcm_dv.device.system.date);
    console.log("[get] device.system.ip_addr = ", 
                mcm_dv.device.system.ip_addr);
    console.log("[get] device.system.uptime = ", 
                mcm_dv.device.system.uptime);
    console.log("[get] device.system.loading = ", 
                mcm_dv.device.system.loading);

    console.log("[get] device.vap.@3.ekey = ",
                mcm_dv.device.vap[2].ekey);
    console.log("[get] device.vap.@3.ssid = ",
                mcm_dv.device.vap[2].ssid);
    console.log("[get] device.vap.@3.channel = ",
                mcm_dv.device.vap[2].channel);

    console.log("[get] device.vap.@2.station.@1.ekey = ",
                mcm_dv.device.vap[1].station[0].ekey);
    console.log("[get] device.vap.@2.station.@1.mac_addr = ",
                mcm_dv.device.vap[1].station[0].mac_addr);
    console.log("[get] device.vap.@2.station.@1.rule = ",
                mcm_dv.device.vap[1].station[0].rule);

    console.log("[get] device.limit.@1.ekey = ",
                mcm_dv.device.limit[0].ekey);
    console.log("[get] device.limit.@1.name = ",
                mcm_dv.device.limit[0].name);
    console.log("[get] device.limit.@1.priority = ",
                mcm_dv.device.limit[0].priority);
}
</script>
</head>
<body>
  <button type="button" onclick="main_init()">test</button>
</body>
</html>


範例 : 所有類型資料都使用字串格式輸出
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
function main_init()
{
    var self_jslib, req_cmd, mcm_dv;

    req_cmd = "&get.device" +
              "&get.device.system";

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.ro;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    // 所有類型資料都使用字串格式輸出.
    self_jslib.data_format = mcm_data_format.all_string;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_obtain_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_obtain_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_dv = JSON.parse(rep_ret.rep_data);

    console.log("[get] device.descript = ", 
                mcm_dv.device.descript);
    console.log("[get] device.serial_number = ", 
                mcm_dv.device.serial_number);

    console.log("[get] device.system.date = ", 
                mcm_dv.device.system.date);
    console.log("[get] device.system.ip_addr = ", 
                mcm_dv.device.system.ip_addr);
    console.log("[get] device.system.uptime = ", 
                mcm_dv.device.system.uptime);
    console.log("[get] device.system.loading = ", 
                mcm_dv.device.system.loading);
}
</script>
</head>
<body>
  <button type="button" onclick="main_init()">test</button>
</body>
</html>


範例 : isll 和 iull 類型的資料使用字串格式輸出
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
function main_init()
{
    var self_jslib, req_cmd, mcm_dv;

    req_cmd = "&get.device" +
              "&get.device.system";

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.ro;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    // isll 和 iull 類型的資料使用字串格式輸出.
    self_jslib.data_format = mcm_data_format.all_default |
        mcm_data_format.isll_string | mcm_data_format.iull_string;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_obtain_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_obtain_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_dv = JSON.parse(rep_ret.rep_data);

    console.log("[get] device.descript = ", 
                mcm_dv.device.descript);
    console.log("[get] device.serial_number = ", 
                mcm_dv.device.serial_number);

    console.log("[get] device.system.date = ", 
                mcm_dv.device.system.date);
    console.log("[get] device.system.ip_addr = ", 
                mcm_dv.device.system.ip_addr);
    console.log("[get] device.system.uptime = ", 
                mcm_dv.device.system.uptime);
    console.log("[get] device.system.loading = ", 
                mcm_dv.device.system.loading);
}
</script>
</head>
<body>
  <button type="button" onclick="main_init()">test</button>
</body>
</html>

寫入資料到 member (set)

格式 :
"&set.$(full_path)=$(value)"

$(full_path) 目標的路徑 [詳細]
[member 格式][key 模式]
$(value) 要寫入的資料

注意事項 :
01.  資料存取模式必須是 mcm_session_permission.rw.
02.  字串類型的資料如果有值要用 mcm_jslib_convert_submit_str() 調整過.
03.  字節流類型的資料如果有值要用 雙位數 16 進制 (大小寫皆可) 格式.

建立指令.
範例 :
var req_cmd = "", tmp_data;

// 設定 device
tmp_data = "網路設備-" + Math.floor(Math.random() * 10);
req_cmd += "&set.device.descript=" +
           mcm_jslib_convert_submit_str(tmp_data);
req_cmd += "&set.device.serial_number=" + "0120A6B70099";

// 設定 device.system.uptime
tmp_data = Math.floor(Math.random() * 1000000000);
req_cmd += "&set.device.system.uptime=" + tmp_data;
// 設定 device.system.loading
tmp_data = Math.random() * 500;
req_cmd += "&set.device.system.loading=" + tmp_data;

// 設定 device.vap.#23
tmp_data = "ssid " + Math.floor(Math.random() * 20);
req_cmd += "&set.device.vap.#23.ssid=" +
           mcm_jslib_convert_submit_str(tmp_data);
tmp_data = Math.floor(Math.random() * 200);
req_cmd += "&set.device.vap.#23.channel=" + tmp_data;

// 設定 device.vap.#8.extra.tx_power
tmp_data = Math.floor(Math.random() * 120);
req_cmd += "&set.device.vap.#8.extra.tx_power=" + tmp_data;

// 設定 device.vap.#15.station.#30
tmp_data = "00:11:aa:22:bb:" + Math.floor(Math.random() * 100);
req_cmd += "&set.device.vap.#15.station.#30.mac_addr=" +
           mcm_jslib_convert_submit_str(tmp_data);
tmp_data = Math.floor(Math.random() * 10);
req_cmd += "&set.device.vap.#15.station.#30.rule=" + tmp_data;

// 設定 device.limit.#6.name
req_cmd += "&set.device.limit.#6.name=" +
           mcm_jslib_convert_submit_str("")


指令建立後, 使用 mcm_jslib_submit_config() 送出請求, 之後檢查返回的結果是否成功.
範例 :
var self_jslib, rep_ret;

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.rw;
self_jslib.session_stack_size = 0;
self_jslib.request_command = req_cmd;
self_jslib.after_complete = mcm_after_complete.reload;
self_jslib.other_query = "";
rep_ret = mcm_jslib_submit_config(self_jslib);
if(rep_ret.rep_code < mcm_return_code.pass)
{
    alert("call mcm_jslib_submit_config() fail" +
          "[" + rep_ret.rep_code + "]");
    mcm_jslib_run_script(rep_ret.rep_data);
    return;
}
mcm_jslib_run_script(rep_ret.rep_data);


完整程式 :
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
var req_cmd = "";
function main_command()
{
    var tmp_data, tmp_cmd;

    req_cmd = "";
    console.clear();

    tmp_data = "網路設備-" + Math.floor(Math.random() * 10);
    tmp_cmd = "&set.device.descript=" +
              mcm_jslib_convert_submit_str(tmp_data);
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);

    tmp_data = "120A0BF" + Math.floor(Math.random() * 10);
    tmp_cmd = "&set.device.serial_number=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);


    tmp_data = Math.floor(Math.random() * 1000000000);
    tmp_cmd = "&set.device.system.uptime=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);

    tmp_data = Math.random() * 500;
    tmp_cmd = "&set.device.system.loading=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);


    tmp_data = "ssid " + Math.floor(Math.random() * 20);
    tmp_cmd = "&set.device.vap.#23.ssid=" +
              mcm_jslib_convert_submit_str(tmp_data);
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);

    tmp_data = Math.floor(Math.random() * 200);
    tmp_cmd = "&set.device.vap.#23.channel=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);


    tmp_data = Math.floor(Math.random() * 120);
    tmp_cmd = "&set.device.vap.#8.extra.tx_power=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);


    tmp_data = "00:11:aa:22:bb:" + Math.floor(Math.random() * 100);
    tmp_cmd = "&set.device.vap.#15.station.#30.mac_addr=" +
              mcm_jslib_convert_submit_str(tmp_data);
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);

    tmp_data = Math.floor(Math.random() * 10);
    tmp_cmd = "&set.device.vap.#15.station.#30.rule=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);


    tmp_cmd = "&set.device.limit.#6.name=" +
              mcm_jslib_convert_submit_str("");
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);
}
function main_submit()
{
    var self_jslib, rep_ret;

    if(req_cmd == "")
        return;

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.rw;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    self_jslib.after_complete = mcm_after_complete.reload;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_submit_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_submit_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_jslib_run_script(rep_ret.rep_data);
}
</script>
</head>
<body>
  <button type="button" onclick="main_command()">01. command</button>
  <button type="button" onclick="main_submit()">02. submit</button>
</body>
</html>


範例 : 設定 CGI 端處理完後預設不回傳訊息
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
var req_cmd = "";
function main_command()
{
    var tmp_data, tmp_cmd;

    req_cmd = "";
    console.clear();

    tmp_data = "網路設備-" + Math.floor(Math.random() * 10);
    tmp_cmd = "&set.device.descript=" +
              mcm_jslib_convert_submit_str(tmp_data);
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);
}
function main_submit()
{
    var self_jslib, rep_ret;

    if(req_cmd == "")
        return;

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.rw;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    // 設定 CGI 端處理完後預設不回傳訊息.
    self_jslib.after_complete = mcm_after_complete.none;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_submit_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_submit_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }

    // 預設不回傳訊息, 不需要執行.
    //mcm_jslib_run_script(rep_ret.rep_data);
}
</script>
</head>
<body>
  <button type="button" onclick="main_command()">01. command</button>
  <button type="button" onclick="main_submit()">02. submit</button>
</body>
</html>

增加一筆 entry (add)

格式 :
"&add.$(full_path)=$(insert_path)"

$(full_path) 目標的路徑 [詳細]
[entry 格式][key 模式]
$(insert_path) 要插入到何處的路徑 [詳細]
[key 模式]

注意事項 :
01.  資料存取模式必須是 mcm_session_permission.rw.
02.  增加的資料的 key 值不可和存在的資料的 key 相同, 否則會操作失敗.
03.  增加資料後要使用 set 替資料設值, 否則會使用資料模型中設定的初始值.
04.  增加多層資料時, 要逐層增加.

建立指令.
範例 :
var req_cmd = "", tmp_data;

// 增加 device.vap.#123, 放在串列尾端 ("").
req_cmd += "&add.device.vap.#123=";
tmp_data = "public-" + Math.floor(Math.random() * 20);
req_cmd += "&set.device.vap.#123.ssid=" +
           mcm_jslib_convert_submit_str(tmp_data);
tmp_data = Math.floor(Math.random() * 200);
req_cmd += "&set.device.vap.#123.channel=" + tmp_data;

// device.vap.*.extra 是 device.vap.* 的 child-group 而且又是 gs 類型,
// 所以增加 device.vap.#123 後, 資料庫會自動增加 device.vap.#123.extra,
// 替 device.vap.#123.extra 加上值. (不設的話就是使用資料模型中設定的初始值)
tmp_data = Math.floor(Math.random() * 10) % 2;
req_cmd += "&set.device.vap.#123.extra.hidden=" + tmp_data;
tmp_data = Math.floor(Math.random() * 20);
req_cmd += "&set.device.vap.#123.extra.txpower=" + tmp_data;

// 增加 device.vap.#234.station.#1, 插入到第 1 筆 entry 之前 (假設第 1 筆資料的 key 是 8 (#8)).
// 一開始 device.vap.#234 並不存在, 所以要逐層增加.
// 增加 device.vap.#234
// 不設值使用初始值.
req_cmd += "&add.device.vap.#234=";
// 增加 device.vap.#234.station.#1
req_cmd += "&add.device.vap.#234.station.#1=#8";
tmp_data = "00:AA:22:BB:33:" + Math.floor(Math.random() * 100);
req_cmd += "&set.device.vap.#234.station.#1.mac_addr=" +
           mcm_jslib_convert_submit_str(tmp_data);
tmp_data = Math.floor(Math.random() * 20);
req_cmd += "&set.device.vap.#234.station.#1.rule=" + tmp_data;

// 增加 device.limit.#51, 插入到 key 為 60 的 entry 之前 (#60).
// 不設值使用初始值.
req_cmd += "&add.device.limit.#51=#60";


指令建立後, 使用 mcm_jslib_submit_config() 送出請求, 之後檢查返回的結果是否成功.
範例 :
var self_jslib, rep_ret;

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.rw;
self_jslib.session_stack_size = 0;
self_jslib.request_command = req_cmd;
self_jslib.after_complete = mcm_after_complete.reload;
self_jslib.other_query = "";
rep_ret = mcm_jslib_submit_config(self_jslib);
if(rep_ret.rep_code < mcm_return_code.pass)
{
    alert("call mcm_jslib_submit_config() fail" +
          "[" + rep_ret.rep_code + "]");
    mcm_jslib_run_script(rep_ret.rep_data);
    return;
}
mcm_jslib_run_script(rep_ret.rep_data);


完整程式 :
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
var req_cmd = "";
function main_command()
{
    var tmp_data, tmp_cmd;

    req_cmd = "";
    console.clear();

    tmp_cmd = "&add.device.vap.#123=";
    req_cmd += tmp_cmd;
    console.log("[add] ", tmp_cmd);

    tmp_data = "public-" + Math.floor(Math.random() * 20);
    tmp_cmd = "&set.device.vap.#123.ssid=" +
              mcm_jslib_convert_submit_str(tmp_data);
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);

    tmp_data = Math.floor(Math.random() * 200);
    tmp_cmd = "&set.device.vap.#123.channel=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);


    tmp_data = Math.floor(Math.random() * 10) % 2;
    tmp_cmd = "&set.device.vap.#123.extra.hidden=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);

    tmp_data = Math.floor(Math.random() * 20);
    tmp_cmd = "&set.device.vap.#123.extra.tx_power=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);


    tmp_cmd = "&add.device.vap.#234=";
    req_cmd += tmp_cmd;
    console.log("[add] ", tmp_cmd);

    tmp_cmd = "&add.device.vap.#234.station.#1=#8";
    req_cmd += tmp_cmd;
    console.log("[add] ", tmp_cmd);

    tmp_data = "00:AA:22:BB:33:" + Math.floor(Math.random() * 100);
    tmp_cmd = "&set.device.vap.#234.station.#1.mac_addr=" +
              mcm_jslib_convert_submit_str(tmp_data);
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);

    tmp_data = Math.floor(Math.random() * 20);
    tmp_cmd = "&set.device.vap.#234.station.#1.rule=" + tmp_data;
    req_cmd += tmp_cmd;
    console.log("[set] ", tmp_cmd);


    tmp_cmd = "&add.device.limit.#51=#60";
    req_cmd += tmp_cmd;
    console.log("[add] ", tmp_cmd);
}
function main_submit()
{
    var self_jslib, rep_ret;

    if(req_cmd == "")
        return;

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.rw;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    self_jslib.after_complete = mcm_after_complete.reload;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_submit_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_submit_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_jslib_run_script(rep_ret.rep_data);
}
</script>
</head>
<body>
  <button type="button" onclick="main_command()">01. command</button>
  <button type="button" onclick="main_submit()">02. submit</button>
</body>
</html>

刪除一筆 entry (del)

格式 :
"&del.$(full_path)"

$(full_path) 目標的路徑 [詳細]
[entry 格式][key 模式]

注意事項 :
01.  資料存取模式必須是 mcm_session_permission.rw.

建立指令.
範例 :
var req_cmd = "";

// 刪除 device.vap.#8
req_cmd += "&del.device.vap.#8";

// 刪除 device.vap.#15.station.#30
req_cmd += "&del.device.vap.#15.station.#30";


指令建立後, 使用 mcm_jslib_submit_config() 送出請求, 之後檢查返回的結果是否成功.
範例 :
var self_jslib, rep_ret;

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.rw;
self_jslib.session_stack_size = 0;
self_jslib.request_command = req_cmd;
self_jslib.after_complete = mcm_after_complete.reload;
self_jslib.other_query = "";
rep_ret = mcm_jslib_submit_config(self_jslib);
if(rep_ret.rep_code < mcm_return_code.pass)
{
    alert("call mcm_jslib_submit_config() fail" +
          "[" + rep_ret.rep_code + "]");
    mcm_jslib_run_script(rep_ret.rep_data);
    return;
}
mcm_jslib_run_script(rep_ret.rep_data);


完整程式 :
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
var req_cmd = "";
function main_command()
{
    var tmp_data, tmp_cmd;

    req_cmd = "";
    console.clear();

    tmp_cmd = "&del.device.vap.#8";
    req_cmd += tmp_cmd;
    console.log("[del] ", tmp_cmd);

    tmp_cmd = "&del.device.vap.#15.station.#30";
    req_cmd += tmp_cmd;
    console.log("[del] ", tmp_cmd);
}
function main_submit()
{
    var self_jslib, rep_ret;

    if(req_cmd == "")
        return;

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.rw;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    self_jslib.after_complete = mcm_after_complete.reload;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_submit_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_submit_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_jslib_run_script(rep_ret.rep_data);
}
</script>
</head>
<body>
  <button type="button" onclick="main_command()">01. command</button>
  <button type="button" onclick="main_submit()">02. submit</button>
</body>
</html>

刪除所有 entry (delall)

格式 :
"&delall.$(mix_path)"

$(mix_path) 目標的路徑 [詳細]
[key 模式]

注意事項 :
01.  資料存取模式必須是 mcm_session_permission.rw.

建立指令.
範例 :
var req_cmd = "";

// 刪除 device.vap.#15.station.*
req_cmd += "&delall.device.vap.#15.station.*";

// 刪除 device.limit.*
req_cmd += "&delall.device.limit.*";


指令建立後, 使用 mcm_jslib_submit_config() 送出請求, 之後檢查返回的結果是否成功.
範例 :
var self_jslib, rep_ret;

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.rw;
self_jslib.session_stack_size = 0;
self_jslib.request_command = req_cmd;
self_jslib.after_complete = mcm_after_complete.reload;
self_jslib.other_query = "";
rep_ret = mcm_jslib_submit_config(self_jslib);
if(rep_ret.rep_code < mcm_return_code.pass)
{
    alert("call mcm_jslib_submit_config() fail" +
          "[" + rep_ret.rep_code + "]");
    mcm_jslib_run_script(rep_ret.rep_data);
    return;
}
mcm_jslib_run_script(rep_ret.rep_data);


完整程式 :
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
var req_cmd = "";
function main_command()
{
    var tmp_data, tmp_cmd;

    req_cmd = "";
    console.clear();

    tmp_cmd = "&delall.device.vap.#15.station.*";
    req_cmd += tmp_cmd;
    console.log("[delall] ", tmp_cmd);

    tmp_cmd = "&delall.device.limit.*";
    req_cmd += tmp_cmd;
    console.log("[delall] ", tmp_cmd);
}
function main_submit()
{
    var self_jslib, rep_ret;

    if(req_cmd == "")
        return;

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.rw;
    self_jslib.session_stack_size = 0;
    self_jslib.request_command = req_cmd;
    self_jslib.after_complete = mcm_after_complete.reload;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_submit_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_submit_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_jslib_run_script(rep_ret.rep_data);
}
</script>
</head>
<body>
  <button type="button" onclick="main_command()">01. command</button>
  <button type="button" onclick="main_submit()">02. submit</button>
</body>
</html>

執行 mint_cm/mcm_daemon/mcm_module 內的模組函式 (run)

格式 :
"&run.$(module_function)"

$(module_function) 目標的函式名稱

注意事項 :
01.  如果內部模組函式只需要讀取資料, 資料存取模式可以是 mcm_session_permission.ro 或 mcm_session_permission.rw, 如果內部模組函式需要修改資料, 資料存取模必須是 mcm_session_permission.rw.
02.  因為內部模組函式的內容是客制化的, 所以需要的堆疊空間不固定 (區域變數的多寡和函式呼叫的層數都會影響需要的堆疊空間), 透過 session_stack_size 調整伺服器端處理此連線的執行緒的堆疊空間.

建立指令.
範例 :
var req_cmd = "";

// 執行 mcm_module_web_test_01
req_cmd += "&run.mcm_module_web_test_01";


指令建立後, 使用 mcm_jslib_submit_config() 送出請求, 之後檢查返回的結果是否成功.
範例 :
var self_jslib, rep_ret;

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.ro;
self_jslib.session_stack_size = 1048576;
self_jslib.request_command = req_cmd;
self_jslib.after_complete = mcm_after_complete.reload;
self_jslib.other_query = "";
rep_ret = mcm_jslib_submit_config(self_jslib);
if(rep_ret.rep_code < mcm_return_code.pass)
{
    alert("call mcm_jslib_submit_config() fail" +
          "[" + rep_ret.rep_code + "]");
    mcm_jslib_run_script(rep_ret.rep_data);
    return;
}
mcm_jslib_run_script(rep_ret.rep_data);


完整程式 :
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery_main.js"></script>
<script type="text/javascript" src="json3.js"></script>
<script type="text/javascript" src="mcm_jslib_api.js"></script>
<script type="text/javascript" src="mcm_jslib_data_info_auto.js"></script>
<script type="text/javascript">
var req_cmd = "";
function main_command()
{
    var tmp_data, tmp_cmd;

    req_cmd = "";
    console.clear();

    tmp_cmd = "&run.mcm_module_web_test_01";
    req_cmd += tmp_cmd;
    console.log("[run] ", tmp_cmd);
}
function main_submit()
{
    var self_jslib, rep_ret;

    if(req_cmd == "")
        return;

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    self_jslib.session_permission = mcm_session_permission.ro;
    self_jslib.session_stack_size = 1048576;
    self_jslib.request_command = req_cmd;
    self_jslib.after_complete = mcm_after_complete.reload;
    self_jslib.other_query = "";
    rep_ret = mcm_jslib_submit_config(self_jslib);
    if(rep_ret.rep_code < mcm_return_code.pass)
    {
        alert("call mcm_jslib_submit_config() fail" +
              "[" + rep_ret.rep_code + "]");
        mcm_jslib_run_script(rep_ret.rep_data);
        return;
    }
    mcm_jslib_run_script(rep_ret.rep_data);
}
</script>
</head>
<body>
  <button type="button" onclick="main_command()">01. command</button>
  <button type="button" onclick="main_submit()">02. submit</button>
</body>
</html>

模組部分 :
這部分程式要放在 mint_cm/mcm_daemon/mcm_module 之下, 檔案名稱隨意 (*.c),
之後在 mint_cm 使用 make all 重新編譯.

#include <time.h>
#include <stdio.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_web_test_01(
    struct mcm_service_session_t *this_session)
{
    srand(time(NULL));

    DMSG("module-%u", rand());

    return MCM_RCODE_PASS;
}


指令的混合使用

在實際情況下, 指令需要混合使用來完成工作, 這邊說明如何使用以及使用的時機.

在取值 (使用 mcm_jslib_obtain_config()) 的情況

可以混用的指令有 [get] [set] [add] [del] [delall] [run]

使用的時機 :
要取得的資料必須先從系統中取出, 再放到資料庫中供讀取. [詳細]

使用方式 :
01.  使用 [run] 執行內部模組, 並在內部模組中實作將資料從系統中取出放到資料庫的部分.
02.  使用 [get] 取出資料.

範例 :
var self_jslib, req_cmd, rep_ret;

// 執行 mcm_module_get_uptime(), 取得 device.system.loading
req_cmd += "&run.module_get_loading" +
           "&get.device.system";

// 執行 mcm_module_get_client(), 取得 device.client.*
req_cmd += "&run.module_get_client" +
           "&get.device.client.*";

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.rw;
self_jslib.session_stack_size = 0;
self_jslib.request_command = req_cmd;
self_jslib.data_format = mcm_data_format.all_default;
self_jslib.other_query = "";
rep_ret = mcm_jslib_obtain_config(self_jslib);
...


注意事項 :
01.  程式會依照指令的順序執行, 如果 [get] 在 [set] [add] [del] [delall] [run] 之前, 會讀不到修改的資料.
02.  可以使用多個 [run] 分別處理不同種類的資料, 也可以只使用一個 [run] 處理全部的資料.
03.  使用多個 [run] 時, 如果其中一個內部模組返回錯誤 (小於 MCM_RCODE_PASS), 則後續的指令都不會被執行.
04.  其他進階的注意事項參考 #04-07#.

在設值 (使用 mcm_jslib_submit_config()) 的情況

可以混用的指令有, [set] [add] [del] [delall] [run]

使用的時機 :
資料送入資料庫後, 需要用這些資料對系統做實際的設定. [詳細]

使用方式 :
01.  使用 [set] [add] [del] [delall] 修改資料.
02.  使用 [run] 執行內部模組, 並在內部模組中實作將修改的資料套用到系統的部分.

範例程式 :
var self_jslib, req_cmd, rep_ret;

// 設定 device.system.ip_addr
req_cmd += "&set.device.system.ip_addr=" +
           mcm_jslib_convert_submit_str("192.168.100.1");
req_cmd += "&run.module_config_sytem";


// 設定 device.vap.#8
req_cmd += "&set.device.vap.#8.ssid=" +
           mcm_jslib_convert_submit_str("private-networ");
req_cmd += "&set.device.vap.#8.channel=11";

// 刪除 device.vap.#15
req_cmd += "&del.device.vap.#15";

// 增加 device.vap.#55
req_cmd += "&add.device.vap.#55=";
req_cmd += "&set.device.vap.#55.ssid=" +
           mcm_jslib_convert_submit_str("public-networ");
req_cmd += "&set.device.vap.#55.channel=44";

// 處理 device.vap.*
req_cmd += "&run.module_config_vap";

self_jslib = new mcm_jslib_lib_t();
self_jslib.socket_path = "@mintcm";
self_jslib.session_permission = mcm_session_permission.rw;
self_jslib.session_stack_size = 0;
self_jslib.request_command = req_cmd;
self_jslib.after_complete = mcm_after_complete.reload;
self_jslib.other_query = "";
rep_ret = mcm_jslib_submit_config(self_jslib);
...


注意事項 :
01.  程式會依照指令的順序執行, 如果 [run] 在 [set] [add] [del] [delall] 之前, 在內部模組中會讀不到修改的值.
02.  可以使用多個 [run] 分別處理不同種類的資料, 也可以只使用一個 [run] 處理全部的資料.
03.  使用多個 [run] 時, 如果其中一個內部模組返回錯誤 (小於 MCM_RCODE_PASS), 則後續的指令都不會被執行.

後續的章節會說明在模組中如何存取資料.


額外的操作

如果需要使用用戶端或核心端的 save 和 shutwodn 功能, 需要使用 [run] 執行內部模組, 之後在內部模組中使用對映的 save 和 shutdown 函式處理 (#04-07#).


注意事項

如果要透過修改設定資料檔案來做讀取測試的話, 步驟 :
先關閉 mcm_daemon (有在執行的話), 修改設定值檔案, 重新執行 mcm_daemon.
修改設定值檔案有二個方法 :
初始值檔案
mcm_store_profile_default.txt
因為 mcm_daemon 會先讀取現在值檔案, 不存在才讀取初始值檔, 所以每次改好後執行 mcm_daemon 之前要先將現在值檔案刪除.
檔案內容格式 [詳細]
現在值檔案
mcm_store_profile_current.txt
檔案內容格式和初始值檔案相同 [詳細]

使用 [set] [add] [del] [delall] 操作後, 只要該 group 在資料模型中的 $(save) 為 1, 資料就會在寫回現在值的檔案, 所以除了使用列印的方式觀察之外也可以直接看檔案內容.


範例程式的使用

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


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


03.  先修改 mini_httpd 讀取網頁的路徑.
修改 mint_cm/http_server/mini_httpd/last/mini_httpd.conf,
裡面的 dir=/mint_cm/run 必須改成 mint_cm/run 資料夾實際的路徑.


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


05.  web_app 是範例程式.

範例項目 :
case-01 取得最大資料筆數
case-02 讀取資料筆數和資料內容
case-03 設定資料(單筆資料類型)
case-04a 增加資料(多筆資料類型)
case-04b 設定資料(多筆資料類型)
case-04c 刪除資料(多筆資料類型)
case-05a 增加資料(多筆資料類型)(多層架構)
case-05b 設定資料(多筆資料類型)(多層架構)
case-05c 刪除資料(多筆資料類型)(多層架構)
case-06 增加資料-插入模式(多筆資料類型)
case-07 執行模組
case-08 執行模組-儲存資料
case-09 執行模組-結束 mcm_daemon


06.  mini_httpd 執行方法, 進入 mint_cm/run 目錄, 指令 :
./mini_httpd -C mini_httpd.conf


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


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


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


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