chapter 05-04

使用方式 (網頁端)

此章節說明如何在網頁端程式使用.

網頁端無法傳送資料給內部模組, 不過內部模組可以回傳資料給 CGI, 再由 CGI 輸出給網頁端, 需要注意內部模組回傳的資料必須是字串格式.


變數格式的說明

[req_con]
mcm_jslib_obtain_max_count(), mcm_jslib_obtain_config(), mcm_jslib_submit_config() 回傳的資訊.
會使用到的結構成員 :
rep_code 內部模組回傳的執行結果 [詳細]
rep_data 內部模組回傳的字串內容 [詳細]


各種函式的行為限制

mcm_jslib_obtain_max_count

01.  rep_code 的值小於 MCM_RCODE_PASS 代表 rep_data 是錯誤訊息, 訊息內容是 CGI 部分填入, 固定是 JavaScript 格式.

範例 : 指令內指定錯誤的路徑.
網頁程式部分

<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 do_test()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    // 錯誤的路徑, 應該是 device.system
    req_cmd = "&get.device.sys";

    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);
}
</script>
</head>
<body>
  <button type="button" onclick="do_test()">test</button>
</body>
</html>

mcm_jslib_obtain_config

01.  rep_code 的值小於 MCM_RCODE_PASS 代表 rep_data 是錯誤訊息.
02.  如果處理指令發生錯誤, 而且錯誤的原因不是由內部模組設定的 (例如指令內指定錯誤的資訊), 訊息內容會由 CGI 部分填入, 固定是 JavaScript 格式.
03.  使用內部模組設定錯誤訊息時, 格式沒有限制.
04.  如果使用 run 執行多個內部模組, 只會得到最後一個被執行的內部模所組設定的錯誤訊息.

範例 : 指令內指定錯誤的路徑.
網頁程式部分

<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 do_test()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    // 錯誤的路徑, 應該是 device.system
    req_cmd = "&get.device.sys";

    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);
}
</script>
</head>
<body>
  <button type="button" onclick="do_test()">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 do_test()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    req_cmd = "&run.mcm_module_obtain_error_test" +
              "&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_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);
}
</script>
</head>
<body>
  <button type="button" onclick="do_test()">test</button>
</body>
</html>

內部模組部分

#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_obtain_error_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len;
    char *tmp_buf;

    DMSG("obtain error test :");

    tmp_len = 128;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "alert(\"custom error\");");
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

FREE_01:
    return fret;
}


範例 : 執行多個內部模組.
網頁程式部分

<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 do_test()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    // 執行多個內部模組, 只會得到最後一個被執行的內部模組所設定的錯誤訊息,
    // mcm_module_obtain_multiple_test_01() 設定錯誤會馬上返回不會繼續處理指令,
    // 所以 mcm_module_obtain_multiple_test_02() 不會被執行到.
    req_cmd = "&run.mcm_module_obtain_multiple_test_01" +
              "&run.mcm_module_obtain_multiple_test_02" +
              "&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_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);
}
</script>
</head>
<body>
  <button type="button" onclick="do_test()">test</button>
</body>
</html>

內部模組部分

#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_obtain_multiple_test_01(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len;
    char *tmp_buf;

    DMSG("obtain multiple test 01 :");

    tmp_len = 128;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "custom error 01");
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

FREE_01:
    return fret;
}

int mcm_module_obtain_multiple_test_02(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len;
    char *tmp_buf;

    DMSG("obtain multiple test 02 :");

    tmp_len = 128;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "custom error 02");
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

FREE_01:
    return fret;
}


範例 : 進階 get 處理, 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">
function main_init()
{
    var self_jslib, req_cmd = "", rep_ret, mcm_dv, i, j;

    // 把要過濾的規則寫入到資料庫, 之後內部模組函式再從資料庫讀出過濾規則.
    req_cmd += "&set.device.filter.rule1=" +
               $("#rule_select").val();

    // 指定要讀出的資料.
    req_cmd += "&get.device.vap.*.station.*=find_match_rule_station" +
               // vap 和 station 路徑有階層關係, 需要注意順序,
               // 因為是要找出指定的 station 所屬的 vap 資料,
               // 所以 vap 指令必須在 station 指令之後.
               "&get.device.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.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);

    for(i = 0; i < mcm_dv.device.vap.length; i++)
    {
        console.log("device.vap.@" + (i + 1) + ".ekey = " +
                    mcm_dv.device.vap[i].ekey);
        console.log("device.vap.@" + (i + 1) + ".ssid = " +
                    mcm_dv.device.vap[i].ssid);
        console.log("device.vap.@" + (i + 1) + ".channel = " +
                    mcm_dv.device.vap[i].channel);

        for(j = 0; j < mcm_dv.device.vap[i].station.length; j++)
        {
            console.log("device.vap.@" + (i + 1) + ".station.@" + (j + 1) + ".ekey = " +
                        mcm_dv.device.vap[i].station[j].ekey);
            console.log("device.vap.@" + (i + 1) + ".station.@" + (j + 1) + ".mac_addr = " +
                        mcm_dv.device.vap[i].station[j].mac_addr);
            console.log("device.vap.@" + (i + 1) + ".station.@" + (j + 1) + ".rule = " +
                        mcm_dv.device.vap[i].station[j].rule);
        }
    }
}
</script>
</head>
<body>
  <select id="rule_select">
    <option value="1">find phone (rule = 1) station</option>
    <option value="2">find mobile (rule = 2) station</option>
    <option value="3">find geme (rule = 3) station</option>
    <option value="4">find stream (rule = 4) station</option>
    <option value="5">find remote (rule = 5) station</option>
    <option value="6">find control (rule = 6) station</option>
    <option value="7">find security (rule = 7) station</option>
    <option value="8">find unknown (rule = 8) station</option>
  </select>
  <br>
  <button type="button" onclick="main_init()">test</button>
</body>
</html>

CGI 模組部分

#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"
#include "mcm_cgi_module_debug.h"

int find_match_rule_station(
    struct mcm_lulib_lib_t *this_lulib,
    MCM_DTYPE_USIZE_TD part_level,
    MCM_DTYPE_EK_TD *part_key,
    MCM_DTYPE_EK_TD **key_list_buf,
    MCM_DTYPE_EK_TD *key_count_buf)
{
    int fret;
    char *path1;
    MCM_DTYPE_USIZE_TD pidx, req_len, rep_len;
    MCM_DTYPE_EK_TD req_data[MCM_PATH_MAX_LEVEL], *rep_data;

#if MCM_CCMEMODE | MCM_CCMDMODE
    dbg_console_fd = open(MCM_DBG_CONSOLE, O_WRONLY);
    if(dbg_console_fd == -1)
        return MCM_RCODE_CGI_CONFIG_INTERNAL_ERROR;
#endif

    MCM_CCMDMSG("part_level = %u", part_level);

    // 依照 | part_key[0] | part_key[1] | ... | part_key[part_level - 1] |,
    // 的順序將資料傳給內部模組.
    req_len = (sizeof(MCM_DTYPE_EK_TD) * part_level);
    for(pidx = 0; pidx < part_level; pidx++)
        req_data[pidx] = part_key[pidx];

    path1 = "mcm_module_obtain_match_rule_station";
    MCM_CCMDMSG("[run] %s", path1);
    fret = mcm_lulib_run(this_lulib, path1, req_data, req_len, (void **) &rep_data, &rep_len);
    if(fret < MCM_RCODE_PASS)
    {
        MCM_CCMDMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_01;
    }

    // 內部模組回傳的資料, 格式 : | key1 | key2 | ... | keyN |.
    *key_list_buf = rep_data;
    *key_count_buf = rep_len / sizeof(MCM_DTYPE_EK_TD);

FREE_01:
#if MCM_CCMEMODE | MCM_CCMDMODE
    close(dbg_console_fd);
#endif
    return fret;
}

內部模組部分

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.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 process_station_vap_part(
    struct mcm_service_session_t *this_session,
    MCM_DTYPE_EK_TD *part_key,
    MCM_DTYPE_EK_TD **key_list_buf,
    MCM_DTYPE_EK_TD *key_count_buf,
    MCM_DTYPE_ISI_TD rule_rule)
{
    int fret;
    char *path1, path2[MCM_PATH_MAX_LENGTH];
    MCM_DTYPE_EK_TD vap_count, *rep_list = NULL, rep_count = 0;
    MCM_DTYPE_BOOL_TD is_match;
    struct mcm_config_model_group_t *vap_group, *station_group;
    struct mcm_config_store_t *device_store, *vap_store, *station_store;
    struct mcm_dv_device_vap_t vap_v;
    struct mcm_dv_device_vap_station_t station_v;

    // 使用進階模式讀取資料, 先取出 device.vap.* 的開頭 store_info.
    path1 = "device.vap.*";
    fret = mcm_config_find_entry_by_mix(this_session, path1, &vap_group, &vap_store, NULL,
                                        NULL, NULL, &device_store);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_find_entry_by_mix(%s) fail", path1);
        goto FREE_01;
    }

    // 取出 vap 的資料數目, 之後配置空間記錄符合的資料的 key.
    fret = mcm_config_get_count_by_info(this_session, vap_group, device_store, &vap_count);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_count_by_info(%s) fail", path1);
        goto FREE_01;
    }

    if(vap_count > 0)
    {
        // 配置空間.
        rep_list = malloc(sizeof(MCM_DTYPE_EK_TD) * vap_count);
        if(rep_list == NULL)
        {
            DMSG("call malloc() fail [%s]", strerror(errno));
            goto FREE_01;
        }

        // 處理每一個 device.vap.*
        for(; vap_store != NULL; vap_store = vap_store->next_store)
        {
            // 讀出 vap 的 key 以便組合 station 的路徑來取出資料.
            fret = mcm_config_get_entry_by_info(this_session, vap_group, vap_store,
                                                MCM_DACCESS_SYS, &vap_v);
            if(fret < MCM_RCODE_PASS)
            {
                DMSG("call mcm_config_get_entry_by_info() fail");
                goto FREE_02;
            }

            // 使用進階模式讀取資料, 取出 device.vap.${vap_v.ekey}.station.* 的開頭 store_info.
            snprintf(path2, sizeof(path2), "device.vap.#%u.station.*", vap_v.ekey);
            fret = mcm_config_find_entry_by_mix(this_session, path2, &station_group,
                                                &station_store, NULL, NULL, NULL, NULL);
            if(fret < MCM_RCODE_PASS)
            {
                DMSG("call mcm_config_find_entry_by_mix(%s) fail", path2);
                goto FREE_02;
            }

            is_match = 0;

            // 處理每一個 device.vap.${vap_v.ekey}.station.*
            for(; station_store != NULL; station_store = station_store->next_store)
            {
                // 讀出 station 資料.
                fret = mcm_config_get_entry_by_info(this_session, station_group, station_store,
                                                    MCM_DACCESS_SYS, &station_v);
                if(fret < MCM_RCODE_PASS)
                {
                    DMSG("call mcm_config_get_entry_by_info() fail");
                    goto FREE_02;
                }

                // 檢查是否符合.
                if(rule_rule == station_v.rule)
                {
                    is_match = 1;
                    break;
                }
            }

            // 把符合的 key 加入到表中.
            if(is_match != 0)
            {
                rep_list[rep_count] = vap_v.ekey;
                rep_count++;
            }
        }
    }

    *key_list_buf = rep_list;
    *key_count_buf = rep_count;

    return fret;
FREE_02:
    free(rep_list);
FREE_01:
    return fret;
}

int process_station_station_part(
    struct mcm_service_session_t *this_session,
    MCM_DTYPE_EK_TD *part_key,
    MCM_DTYPE_EK_TD **key_list_buf,
    MCM_DTYPE_EK_TD *key_count_buf,
    MCM_DTYPE_ISI_TD rule_rule)
{
    int fret;
    char path2[MCM_PATH_MAX_LENGTH];
    MCM_DTYPE_EK_TD target_vap, station_count, *rep_list = NULL, rep_count = 0;
    struct mcm_config_model_group_t *station_group;
    struct mcm_config_store_t *vap_store, *station_store;
    struct mcm_dv_device_vap_station_t station_v;

    // 使用進階模式讀取資料, 取出 device.vap.${target_vap}.station.* 的開頭 store_info.
    target_vap = part_key[1];
    snprintf(path2, sizeof(path2), "device.vap.#%u.station.*", target_vap);
    fret = mcm_config_find_entry_by_mix(this_session, path2, &station_group,
                                        &station_store, NULL, NULL, NULL, &vap_store);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_find_entry_by_mix(%s) fail", path2);
        goto FREE_01;
    }

    // 取出 station 的資料數目, 之後配置空間記錄符合的資料的 key.
    fret = mcm_config_get_count_by_info(this_session, station_group, vap_store, &station_count);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_count_by_info(%s) fail", path2);
        goto FREE_01;
    }

    if(station_count > 0)
    {
        // 配置空間.
        rep_list = malloc(sizeof(MCM_DTYPE_EK_TD) * station_count);
        if(rep_list == NULL)
        {
            DMSG("call malloc() fail [%s]", strerror(errno));
            goto FREE_01;
        }

        // 處理每一個 device.vap.${target_vap}.station.*
        for(; station_store != NULL; station_store = station_store->next_store)
        {
            // 讀出 station 資料.
            fret = mcm_config_get_entry_by_info(this_session, station_group, station_store,
                                                MCM_DACCESS_SYS, &station_v);
            if(fret < MCM_RCODE_PASS)
            {
                DMSG("call mcm_config_get_entry_by_info() fail");
                goto FREE_02;
            }

            // 檢查是否符合.
            if(rule_rule == station_v.rule)
            {
                rep_list[rep_count] = station_v.ekey;
                rep_count++;
            }
        }
    }

    *key_list_buf = rep_list;
    *key_count_buf = rep_count;

    return fret;
FREE_02:
    free(rep_list);
FREE_01:
    return fret;
}

int mcm_module_obtain_match_rule_station(
    struct mcm_service_session_t *this_session)
{
    int fret;
    char *path1;
    MCM_DTYPE_USIZE_TD part_level;
    MCM_DTYPE_EK_TD *part_key, *rep_list = NULL, rep_count = 0;
    MCM_DTYPE_ISI_TD rule_rule;

    DMSG("obtain match rule station test (advance get) :");

    // 取出 CGI 模組傳送的資料,
    // 格式 : | part_key[0] | part_key[1] | ... | part_key[part_level - 1] |.
    part_level = this_session->req_data_len / sizeof(MCM_DTYPE_EK_TD);
    part_key = (MCM_DTYPE_EK_TD *) this_session->req_data_con;

    DMSG("part_level = %u", part_level);

    // 讀出規則.
    path1 = "device.filter.rule1";
    fret = mcm_config_get_alone_by_path(this_session, path1, MCM_DACCESS_AUTO, &rule_rule);
    if(fret < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_get_alone(%s) fail", path1);
        goto FREE_01;
    }
    DMSG("find station (rule = " MCM_DTYPE_ISI_PF ")", rule_rule);

    // 處理 device.vap.*.station.* 的 vap 部分,
    // 回報符合規則的 station 所屬的 vap.
    if(part_level == 2)
    {
        DMSG("process vap part");

        fret = process_station_vap_part(this_session, part_key, &rep_list, &rep_count,
                                        rule_rule);
        if(fret < MCM_RCODE_PASS)
        {
            DMSG("call process_station_vap_part() fail");
            goto FREE_01;
        }
    }
    else
    // 處理 device.vap.*.station.* 的 station 部分,
    // 回報符合規則的 station.
    if(part_level == 3)
    {
        DMSG("process station part");
        DMSG("device.vap.#%u.station.*", part_key[1]);

        fret = process_station_station_part(this_session, part_key, &rep_list, &rep_count,
                                            rule_rule);
        if(fret < MCM_RCODE_PASS)
        {
            DMSG("call process_station_station_part() fail");
            goto FREE_01;
        }
    }

    // 回傳符合的資料, 格式 : | key1 | key2 | ... | keyN |.
    this_session->rep_data_buf = rep_list;
    this_session->rep_data_len = sizeof(MCM_DTYPE_EK_TD) * rep_count;

FREE_01:
    return fret;
}

mcm_jslib_submit_config

01.  如果處理指令發生錯誤, 而且錯誤的原因不是由內部模組設定的 (例如指令內指定錯誤的資訊), 錯誤訊息內容會由 CGI 部分填入, 固定是 JavaScript 格式.
02.  如果處理指令沒有錯誤, 而且沒有指定執行內部模組並填入回傳訊息, CGI 部分會依據 after_complete 來決定要填入哪種訊息.
03.  使用內部模組設定訊息時, 格式沒有限制.
04.  如果使用 run 執行多個內部模組, 只會得到最後一個被執行的內部模組的訊息.

範例 : 錯誤的存取模式.
網頁程式部分

<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 do_test()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    req_cmd = "&set.device.system.uptime=123456789";

    self_jslib = new mcm_jslib_lib_t();
    self_jslib.socket_path = "@mintcm";
    // 錯誤的存取模式, 應該是 mcm_session_permission.rw.
    self_jslib.session_permission = mcm_session_permission.ro;
    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="do_test()">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 do_test()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    req_cmd = "&set.device.system.uptime=123456789" +
              "&run.mcm_module_submit_error_test";

    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="do_test()">test</button>
</body>
</html>

內部模組部分

#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_submit_error_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len;
    char *tmp_buf;

    DMSG("submit error test :");

    tmp_len = 128;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "alert(\"custom error\");");
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

FREE_01:
    return fret;
}


範例 : 處理指令沒有錯誤, 指定 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">
function do_test()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    req_cmd = "&set.device.system.uptime=123456789";

    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="do_test()">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 do_test()
{
    var self_jslib, req_cmd = "", rep_ret;

    req_cmd += "&set.device.descript=" +
               mcm_jslib_convert_submit_str($("#descript_text").val());

    req_cmd += "&run.mcm_module_submit_text_test";

    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;
    }

    // 顯示回傳的文字.
    alert(rep_ret.rep_data);
}
</script>
</head>
<body>
  <table>
    <tr>
      <td>input srting : </td>
      <td>
        <input id="descript_text" type="text" size="32">
      </td>
      <td>
        <button type="button" onclick="do_test()">test</button>
      </td>
    </tr>
  </table>
</body>
</html>

內部模組部分

#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_submit_text_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1, *tmp_buf;
    struct mcm_dv_device_t device_v;
    MCM_DTYPE_USIZE_TD tmp_len;

    DMSG("submit text test :");

    path1 = "device";
    if(mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_AUTO, &device_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    tmp_len = 512;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, " %s", device_v.descript);
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


範例 : 內部模組自訂訊息, JSON 格式.
網頁程式部分

<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 do_test()
{
    var self_jslib, req_cmd = "", rep_ret, custom_data;

    req_cmd += "&set.device.descript=" +
               mcm_jslib_convert_submit_str($("#descript_text").val());

    req_cmd += "&run.mcm_module_submit_json_test";

    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;
    }

    // 處理回傳的內容.
    custom_data = JSON.parse(rep_ret.rep_data);
    alert(custom_data.descript);
}
</script>
</head>
<body>
  <table>
    <tr>
      <td>input srting : </td>
      <td>
        <input id="descript_text" type="text" size="32">
      </td>
      <td>
        <button type="button" onclick="do_test()">test</button>
      </td>
    </tr>
  </table>
</body>
</html>

內部模組部分

#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_submit_json_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1, *tmp_buf;
    struct mcm_dv_device_t device_v;
    MCM_DTYPE_USIZE_TD tmp_len;

    DMSG("submit json test :");

    path1 = "device";
    if(mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_AUTO, &device_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    tmp_len = 512;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "{\"descript\":\"%s\"}", device_v.descript);
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


範例 : 內部模組自訂訊息, JavaScript 格式, 控制網頁元素.
網頁程式部分

<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 do_test()
{
    var self_jslib, req_cmd = "", rep_ret;

    req_cmd += "&set.device.system.uptime=" +
               $("#uptime_text").val();

    req_cmd += "&run.mcm_module_javascript_control_element_test";

    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>
  <table>
    <tr>
      <td>input number : </td>
      <td>
        <input id="uptime_text" type="text" size="8" value="0">
      </td>
      <td>
        <button type="button" onclick="do_test()">submit</button>
      </td>
      <td>
        <div id="number_div"></div>
      </td>
    </tr>
  </table>
</body>
</html>

內部模組部分

#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_javascript_control_element_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1, *tmp_buf;
    struct mcm_dv_device_system_t system_v;
    MCM_DTYPE_USIZE_TD tmp_len;

    DMSG("submit javascript control element test :");

    path1 = "device.system";
    if(mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_AUTO, &system_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    tmp_len = 512;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len,
             "$(\"#number_div\").html(\""
             "<font color=\\\"#%s\\\">%s number</font>"
             "\");",
             system_v.uptime % 2 == 0 ? "FF0000" : "0000FF",
             system_v.uptime % 2 == 0 ? "even" : "odd");
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


範例 : 內部模組自訂訊息, JavaScript 格式, 頁面導向.
網頁程式部分

<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 do_test()
{
    var self_jslib, req_cmd = "", rep_ret;

    req_cmd += "&set.device.descript=" +
               mcm_jslib_convert_submit_str($("#descript_text").val());

    req_cmd += "&run.mcm_module_submit_javascript_redirect_page_test";

    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>
  <table>
    <tr>
      <td>input url : </td>
      <td>
        <input id="descript_text" type="text" size="32" value="http://www.pchome.com.tw">
      </td>
      <td>
        <button type="button" onclick="do_test()">submit</button>
      </td>
    </tr>
  </table>
</body>
</html>

內部模組部分

#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_submit_javascript_redirect_page_test(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    char *path1, *tmp_buf;
    struct mcm_dv_device_t device_v;
    MCM_DTYPE_USIZE_TD tmp_len;

    DMSG("submit javascript redirect page test :");

    path1 = "device";
    if(mcm_config_get_entry_by_path(this_session, path1, MCM_DACCESS_AUTO, &device_v)
                                    < MCM_RCODE_PASS)
    {
        DMSG("call mcm_config_get_entry_by_path(%s) fail", path1);
        goto FREE_01;
    }

    tmp_len = 512;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "window.location.href = \"%s\";", device_v.descript);
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


範例 : 執行多個內部模組.
網頁程式部分

<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 do_test()
{
    var self_jslib, req_cmd, rep_ret, mcm_dv;

    // 執行多個內部模組, 只會得到最後一個被執行的內部模組的訊息,
    // mcm_module_submit_multiple_test_01() 輸出的訊息會被下一個內部模組覆蓋,
    // 只會輸出 mcm_module_submit_multiple_test_02() 的訊息.
    req_cmd = "&set.device.system.uptime=123456789" +
              "&run.mcm_module_submit_multiple_test_01" +
              "&run.mcm_module_submit_multiple_test_02";

    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;
    }

    alert(rep_ret.rep_data);
}
</script>
</head>
<body>
  <button type="button" onclick="do_test()">test</button>
</body>
</html>

內部模組部分

#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_submit_multiple_test_01(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len;
    char *tmp_buf;

    DMSG("submit multiple test 01 :");

    tmp_len = 128;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "custom message 01");
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

int mcm_module_submit_multiple_test_02(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len;
    char *tmp_buf;

    DMSG("submit multiple test 02 :");

    tmp_len = 128;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "custom message 02");
    tmp_len = strlen(tmp_buf) + 1;

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}


範例程式的使用

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


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


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


04.  web_app 是範例程式.

範例項目 :
case-01 mcm_jslib_obtain_max_count()
指令內指定錯誤的路徑
case-02 mcm_jslib_obtain_config()
指令內指定錯誤的路徑
case-03 mcm_jslib_obtain_config()
由內部模組設定錯誤
case-04 mcm_jslib_obtain_config()
執行多個內部模組
case-05 mcm_jslib_obtain_config()
進階 get 處理, CGI 端的模組函式呼叫內部模組處理資料的過濾
case-06 mcm_jslib_submit_config()
指令內指定錯誤的路徑
case-09 mcm_jslib_submit_config()
由內部模組設定錯誤
case-08 mcm_jslib_submit_config()
處理指令沒有錯誤, CGI 部分填入重新整理頁面的 JavaScript 格式訊息
case-09 mcm_jslib_submit_config()
內部模組自訂訊息, 文字格式
case-10 mcm_jslib_submit_config()
內部模組自訂訊息, JSON 格式
case-11 mcm_jslib_submit_config()
內部模組自訂訊息, JavaScript 格式, 控制網頁元素
case-12 mcm_jslib_submit_config()
內部模組自訂訊息, JavaScript 格式, 頁面導向
case-13 mcm_jslib_submit_config()
執行多個內部模組


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


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


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


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