|
讀出資料 (get)
格式 :
"&get.$(mask_path)=$(function_name)"
注意事項 :
範例 : "&get.device.vap.*=find_5g_vap" 取出 vap 資料時, 執行 CGI 模組的 find_5g_vap() 函式, 指定只取出需要哪幾筆資料. "&get.device.vap.*.station.*=find_mobile_station" 取出 station 資料時, 執行 CGI 模組的 find_idle_station() 函式, 指定只取出需要哪幾筆資料. 備註-01 (只有含有任意一個 gd 類型資料的路徑會執行指定的 CGI 端的處理函式) : "&get.device=update_device" device 是 gs 類型, update_device() 不會被執行. "&get.device.system=get_load" device 和 system 都是 gs 類型, get_load() 不會被執行. "&get.device.vap.*=find_5g_vap" device 是 gs 類型, vap 是 gd 類型, find_5g_vap() 會被執行. "&get.device.vap.*.extra=find_hidden_vap" device 是 gs 類型, vap 是 gd 類型, extra 是 ds 類型, find_hidden_vap() 會被執行. 備註-02a (如果同時設定了多個 get 指令, 而且指令之間有階層關係, 則需要注意指令的順序) :
CGI 端在處理 get 指令時, 會依照路徑的階層由上到下處理.
01. 對於路徑上非最後一層, 檢查是否已經處理過 (多條 get 指令的情況).
01. 沒處理過, 取出資料的索引.
02. 有處理過, 跳過不處理.
02. 對於路徑上的最後一層, 檢查是否已經處理過 (多條 get 指令的情況).
01. 沒處理過, 取出資料的索引和內容.
02. 有處理過, 因為不允許有重複的指令, 所以實際上會是在其他 get 指令的非最後一層被處理,
也就是在其他地方已經取出資料的索引, 補上這些資料的內容.
例如-01 (單條 get 指令) :
req_cmd += "&get.device.vap.*.station.*";
device => 取出資料索引.
vap => 取出每個 device 之下的 vap 的資料索引.
station => 取出每個 vap 之下的 station 的資料索引和內容.
例如-02 (多條 get 指令) :
req_cmd += "&get.device.vap.*" +
"&get.device.vap.*.station.*";
處理 "&get.device.vap.*"
device => 取出資料索引.
vap => 取出每個 device 之下的 vap 的資料索引和內容.
處理 "&get.device.vap.*.station"
device => 已經處理過, 跳過.
vap => 已經處理過, 跳過.
station => 取出每個 vap 之下的 station 的資料索引和內容.
例如-03 (多條 get 指令) :
req_cmd += "&get.device.vap.*.station.*" +
"&get.device.vap.*";
處理 "&get.device.vap.*.station"
device => 取出資料索引.
vap => 取出每個 device 之下的 vap 的資料索引.
station => 取出每個 vap 之下的 station 的資料索引和內容.
處理 "&get.device.vap.*"
device => 已經處理過, 跳過.
vap => 已經處理過 (只有資料索引), 補上這些資料的內容.
在一般模式的情況下多個 get 指令可以不用照順序排列 (範例 02 和 03).
|
| 參數 | 說明 | ||||||||||
|
struct mcm_lulib_lib_t * this_lulib |
紀錄 mcm_lulib_api 的資料 [詳細]
注意事項 :
|
||||||||||
|
MCM_DTYPE_EK_TD part_level |
紀錄目前是要處理第幾層路徑 (1 ~ N)
CGI 處理路徑時會逐層處理, 如果該層路徑是 gd 類型就會呼叫模組函式, 並指出現在是第幾層路徑, 如果路徑上有多個 gd 類型則會呼叫多次模組函式 例如 : "&get.device.vap.*=find_5g_vap" device 是第 1 層, vap 是第 2 層, 處理 vap 時因為是 gd 類型所以會呼叫模組函式, part_level = 2. "&get.device.vap.*.extra=find_hidden_vap" 處理 vap 時因為是 gd 類型所以會呼叫模組函式, part_level = 2, 處理 extra 時因為是 gs 類型所以不會呼叫模組函式. "&get.device.vap.*.station=find_mobile_station" 處理 vap 時因為是 gd 類型所以會呼叫模組函式, part_level = 2, 處理 station 時因為是 gd 類型所以會呼叫模組函式, part_level = 3. |
||||||||||
|
MCM_DTYPE_EK_TD * part_key |
紀錄目前處理的目標的上面幾層的 key 值
如果目標的上層是 gd 類型, 則 CGI 在處理目標層時會根據上層的資料筆數呼叫多次模組函式, 每次呼叫會指出上層的資料的 key 值 注意事項 :
例如 :
"&get.device.vap.*=find_5g_vap"
# 處理 vap 時呼叫模組函式,
vap 的上層 device 是 gs 類型固定只有一筆資料, 所以只會呼叫一次 find_5g_vap(),
- 第 1 次呼叫 find_5g_vap() :
part_level 是 2, part_key 的陣列大小是 2, 內容 :
part_key[0] 表示 device 的 key 值, 因為 device 是 gs 類型所以是 0,
part_key[1] 是最後一個元素, 固定是 0.
"&get.device.vap.*.station.*=find_mobile_station"
# 處理 vap 時呼叫模組函式,
vap 的上層 device 是 gs 類型固定只有一筆資料, 所以只會呼叫一次 find_mobile_station(),
- 處理 vap 時第 1 次呼叫 find_mobile_station() :
part_level = 2, part_key[] = 2 :
part_key[0] = 0,
# 處理 station 時呼叫模組函式,
station 的上層 vap 是 gd 類型有多筆資料, 這時會根據 vap 的資料筆數呼叫多次 find_mobile_station(),
假設 vap 有 3 筆資料, key 值分別是 8, 15, 23,
= 處理 station 時第 1 次呼叫 find_mobile_station() (device.vap.#8) :
part_level = 3, part_key[] = 3 :
part_key[0] = 0,
part_key[1] = 8,
= 處理 station 時第 2 次呼叫 find_mobile_station() (device.vap.#15) :
part_level = 3, part_key[] = 3 :
part_key[0] = 0,
part_key[1] = 15,
= 處理 station 時第 3 次呼叫 find_mobile_station() (device.vap.#23) :
part_level = 3, part_key[] = 3 :
part_key[0] = 0,
part_key[1] = 23.
"&get.device.vap.*.station.*.user.*=find_online_user"
假設資料庫內有這幾筆資料 :
device.vap.#8
device.vap.#8.station.#11
device.vap.#8.station.#13
device.vap.#15
device.vap.#15.station.#24
device.vap.#23
呼叫模組函式的流程 :
# 處理 vap, 呼叫 1 次 find_online_user(),
- 處理 vap 時第 1 次呼叫 find_online_user(),
part_level = 2, part_key[] = 2 :
part_key[0] = 0,
# 處理 station, 呼叫 3 次 find_online_user(),
= 處理 station 時第 1 次呼叫 find_online_user() (device.vap.#8),
part_level = 3, part_key[] = 3 :
part_key[0] = 0,
part_key[1] = 8,
# 處理 user, 呼叫 2 次 find_online_user(),
+ 處理 user 時第 1 次呼叫 find_online_user() (device.vap.#8.station.#11),
part_level = 4, part_key[] = 4 :
part_key[0] = 0,
part_key[1] = 8,
part_key[2] = 11,
+ 處理 user 時第 2 次呼叫 find_online_user() (device.vap.#8.station.#13),
part_level = 4, part_key[] = 4 :
part_key[0] = 0,
part_key[1] = 8,
part_key[2] = 13,
= 處理 station 時第 2 次呼叫 find_online_user() (device.vap.#15),
part_level = 3, part_key[] = 3 :
part_key[0] = 0,
part_key[1] = 15,
# 處理 user, 呼叫 1 次 find_online_user(),
+ 處理 user 時第 1 次呼叫 find_online_user() (device.vap.#15.station.#24),
part_level = 4, part_key[] = 4 :
part_key[0] = 0,
part_key[1] = 15,
part_key[2] = 24,
= 處理 station 時第 3 次呼叫 find_online_user() (device.vap.#23),
part_level = 3, part_key[] = 3 :
part_key[0] = 0,
part_key[1] = 23,
# 處理 user, 呼叫 0 次 find_online_user()
|
||||||||||
|
MCM_DTYPE_EK_TD ** key_list_buf |
資料緩衝, 回報要取出的資料的 key 值 | ||||||||||
|
MCM_DTYPE_EK_TD * key_count_buf |
資料緩衝, 回報要取出的資料筆數 | ||||||||||
|
|
key_list_buf 和 key_count_buf 的注意事項 :
例如 :
// 假設 vap 有 #8, #15, #23, #45 這幾筆資料, 現在要回報 CGI 取出前 3 筆資料.
int find_5g_vap(
struct mcm_lulib_lib_t *this_lulib,
MCM_DTYPE_EK_TD part_level,
MCM_DTYPE_EK_TD *part_key,
MCM_DTYPE_EK_TD **key_list_buf,
MCM_DTYPE_EK_TD *key_count_buf)
{
MCM_DTYPE_EK_TD rep_count, *rep_list;
rep_count = 3;
rep_list = malloc(sizeof(MCM_DTYPE_EK_TD) * rep_count);
rep_list[0] = 8;
rep_list[1] = 15;
rep_list[2] = 23;
*key_list_buf = rep_list;
*key_count_buf = rep_count;
return MCM_CCODE_PASS;
}
// 如果要回報 0 筆資料.
int find_5g_vap(
struct mcm_lulib_lib_t *this_lulib,
MCM_DTYPE_EK_TD part_level,
MCM_DTYPE_EK_TD *part_key,
MCM_DTYPE_EK_TD **key_list_buf,
MCM_DTYPE_EK_TD *key_count_buf)
{
// 不用設定 key_list_buf 和 key_count_buf.
return MCM_CCODE_PASS;
}
|
| 回傳 | 說明 |
| = MCM_RCODE_PASS | 成功 |
| < MCM_RCODE_PASS | 錯誤 |
網頁端
<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;
// 找出使用 5G 設定的 vap.
req_cmd = "&get.device.vap.*=find_5g_vap";
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);
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);
}
}
</script>
</head>
<body>
<button type="button" onclick="main_init()">test</button>
</body>
</html>
CGI 端 (模組函式)
#include <errno.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_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_5g_vap(
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, path2[MCM_PATH_MAX_LENGTH];
struct mcm_dv_device_vap_t *vap_v;
MCM_DTYPE_EK_TD vap_idx, vap_count, *rep_list = NULL, rep_count = 0;
#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);
// 讀出所有的 device.vap.*
path1 = "device.vap.*";
fret = mcm_lulib_get_all_entry(this_lulib, path1, (void **) &vap_v, &vap_count);
if(fret < MCM_RCODE_PASS)
{
MCM_CCMEMSG("call mcm_lulib_get_all_entry(%s) fail", path1);
goto FREE_01;
}
if(vap_count > 0)
{
// 配置空間放置 key (為了方便操作直接配置 vap_count 的數目).
rep_list = (MCM_DTYPE_EK_TD *) malloc(sizeof(MCM_DTYPE_EK_TD) * vap_count);
if(rep_list == NULL)
{
MCM_CCMEMSG("call malloc() fail [%s]", strerror(errno));
goto FREE_02;
}
for(vap_idx = 0; vap_idx < vap_count; vap_idx++)
{
snprintf(path2, sizeof(path2), "device.vap.#%u", vap_v[vap_idx].ekey);
MCM_CCMDMSG("%s.ssid = " MCM_DTYPE_S_PF, path2, vap_v[vap_idx].ssid);
MCM_CCMDMSG("%s.channel = " MCM_DTYPE_IUI_PF, path2, vap_v[vap_idx].channel);
// 檢查是否符合, 是的話把 key 加入到 rep_list.
if(vap_v[vap_idx].channel >= 36)
{
MCM_CCMDMSG("this vap is match");
rep_list[rep_count] = vap_v[vap_idx].ekey;
rep_count++;
}
else
{
MCM_CCMDMSG("this vap is not match");
}
}
}
*key_list_buf = rep_list;
*key_count_buf = rep_count;
FREE_02:
free(vap_v);
FREE_01:
#if MCM_CCMEMODE | MCM_CCMDMODE
close(dbg_console_fd);
#endif
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 main_init()
{
var self_jslib, req_cmd = "", rep_ret, mcm_dv, i, j;
// 把要過濾的規則寫入到資料庫, 之後 CGI 端模組函式再從資料庫讀出過濾規則.
req_cmd += "&set.device.filter.rule1=" +
$("#rule_select").val();
// 找出顯示或隱藏的 vap 以及之下的 extra 資料和 station 資料.
req_cmd += "&get.device.vap.*=find_visible_or_hidden_vap" +
// extra 和 station 路徑和 vap 路徑有階層關係, 需要注意順序,
// 因為是要找出指定的 vap 資料以及之下的 station 資料,
// 所以 extra 和 station 指令必須在 vap 指令之後.
"&get.device.vap.*.extra" +
"&get.device.vap.*.station.*";
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);
// 只會取得符合規則的 vap 的 extra.
console.log("device.vap.@" + (i + 1) + ".extra.hidden = " +
mcm_dv.device.vap[i].extra.hidden);
console.log("device.vap.@" + (i + 1) + ".extra.tx_power = " +
mcm_dv.device.vap[i].extra.tx_power);
// 只會取得符合規則的 vap 的 station.
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="0">find visible vap</option>
<option value="1">find hidden vap</option>
<option value="2">find unknown vap</option>
</select>
<br>
<button type="button" onclick="main_init()">test</button>
</body>
</html>
CGI 端 (模組函式)
#include <errno.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_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_visible_or_hidden_vap(
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, path2[MCM_PATH_MAX_LENGTH];
struct mcm_dv_device_vap_extra_t extra_v;
MCM_DTYPE_ISI_TD get_hidden;
MCM_DTYPE_EK_TD vap_idx, vap_count, *vap_key, *rep_list = NULL, rep_count = 0;
#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);
// 讀出規則.
path1 = "device.filter.rule1";
fret = mcm_lulib_get_alone(this_lulib, path1, &get_hidden);
if(fret < MCM_RCODE_PASS)
{
MCM_CCMEMSG("call mcm_lulib_get_alone(%s) fail", path1);
goto FREE_01;
}
MCM_CCMDMSG("find %s vap", get_hidden == 0 ? "visible" : "hidden");
// 讀出 device.vap.* 所有的 key, 再逐一讀出 device.vap.*.extra
path1 = "device.vap.*";
fret = mcm_lulib_get_all_key(this_lulib, path1, (MCM_DTYPE_EK_TD **) &vap_key, &vap_count);
if(fret < MCM_RCODE_PASS)
{
MCM_CCMEMSG("call mcm_lulib_get_all_key(%s) fail", path1);
goto FREE_01;
}
if(vap_count > 0)
{
// 配置空間放置 key.
rep_list = (MCM_DTYPE_EK_TD *) malloc(sizeof(MCM_DTYPE_EK_TD) * vap_count);
if(rep_list == NULL)
{
MCM_CCMEMSG("call malloc() fail [%s]", strerror(errno));
goto FREE_02;
}
for(vap_idx = 0; vap_idx < vap_count; vap_idx++)
{
// 逐一讀出 device.vap.*.extra
snprintf(path2, sizeof(path2), "device.vap.#%u.extra", vap_key[vap_idx]);
fret = mcm_lulib_get_entry(this_lulib, path2, &extra_v);
if(fret < MCM_RCODE_PASS)
{
MCM_CCMEMSG("call mcm_lulib_get_entry(%s) fail", path2);
goto FREE_02;
}
MCM_CCMDMSG("%s.hidden = " MCM_DTYPE_ISC_PF, path2, extra_v.hidden);
MCM_CCMDMSG("%s.tx_power = " MCM_DTYPE_ISS_PF, path2, extra_v.tx_power);
// 檢查是否符合.
if(get_hidden == extra_v.hidden)
{
MCM_CCMDMSG("this vap is match");
rep_list[rep_count] = vap_key[vap_idx];
rep_count++;
}
else
{
MCM_CCMDMSG("this vap is not match");
}
}
}
*key_list_buf = rep_list;
*key_count_buf = rep_count;
FREE_02:
free(vap_key);
FREE_01:
#if MCM_CCMEMODE | MCM_CCMDMODE
close(dbg_console_fd);
#endif
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 main_init()
{
var self_jslib, req_cmd = "", rep_ret, mcm_dv, i, j;
// 把要過濾的規則寫入到資料庫, 之後 CGI 端模組函式再從資料庫讀出過濾規則.
req_cmd += "&set.device.filter.rule1=" +
$("#rule_select").val();
// 找出符合規則類型的 station 以及所屬的 vap.
req_cmd += "&get.device.vap.*.station.*=find_match_rule_station" +
// vap 指令必須在 station 指令後面,
// 這樣 vap 部分才會只取出符合規則的 station 所屬的 vap.
"&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 <errno.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_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, path2[MCM_PATH_MAX_LENGTH];
struct mcm_dv_device_vap_station_t *station_v;
MCM_DTYPE_ISI_TD target_rule;
MCM_DTYPE_EK_TD vap_idx, vap_count, *vap_key = NULL, target_vap, station_idx, station_count,
rep_idx, *rep_list = NULL, rep_count = 0;
#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);
// 讀出規則.
path1 = "device.filter.rule1";
fret = mcm_lulib_get_alone(this_lulib, path1, &target_rule);
if(fret < MCM_RCODE_PASS)
{
MCM_CCMEMSG("call mcm_lulib_get_alone(%s) fail", path1);
goto FREE_01;
}
MCM_CCMDMSG("find rule (" MCM_DTYPE_ISI_PF ") station", target_rule);
// 處理 device.vap.*.station.* 的 vap 部分,
// 回報符合規則的 station 所屬的 vap.
if(part_level == 2)
{
MCM_CCMDMSG("process vap part");
// 讀出 device.vap.* 所有的 key, 再逐一讀出 device.vap.*.station.*
path1 = "device.vap.*";
fret = mcm_lulib_get_all_key(this_lulib, path1, (MCM_DTYPE_EK_TD **) &vap_key, &vap_count);
if(fret < MCM_RCODE_PASS)
{
MCM_CCMEMSG("call mcm_lulib_get_all_key(%s) fail", path1);
goto FREE_01;
}
if(vap_count > 0)
{
// 配置空間放置 key.
rep_list = (MCM_DTYPE_EK_TD *) malloc(sizeof(MCM_DTYPE_EK_TD) * vap_count);
if(rep_list == NULL)
{
MCM_CCMEMSG("call malloc() fail [%s]", strerror(errno));
goto FREE_02;
}
for(vap_idx = 0; vap_idx < vap_count; vap_idx++)
{
// 讀出 device.vap.#{vap_key[i]}.station.*
snprintf(path2, sizeof(path2), "device.vap.#%u.station.*", vap_key[vap_idx]);
fret = mcm_lulib_get_all_entry(this_lulib, path2, (void **) &station_v,
&station_count);
if(fret < MCM_RCODE_PASS)
{
MCM_CCMEMSG("call mcm_lulib_get_all_entry(%s) fail", path2);
goto FREE_03;
}
for(station_idx = 0; station_idx < station_count; station_idx++)
{
snprintf(path2, sizeof(path2), "device.vap.#%u.station.#%u",
vap_key[vap_idx], station_v[station_idx].ekey);
MCM_CCMDMSG("%s.mac_addr = " MCM_DTYPE_S_PF,
path2, station_v[station_idx].mac_addr);
MCM_CCMDMSG("%s.rule = " MCM_DTYPE_RK_PF,
path2, station_v[station_idx].rule);
//檢查是否符合.
if(target_rule == station_v[station_idx].rule)
{
MCM_CCMDMSG("this vap is match");
// 檢查是否已經在表內, 沒有才加入.
for(rep_idx = 0; rep_idx < rep_count; rep_idx++)
if(rep_list[rep_idx] == vap_key[vap_idx])
break;
if(rep_idx == rep_count)
{
rep_list[rep_count] = vap_key[vap_idx];
rep_count++;
}
}
else
{
MCM_CCMDMSG("this vap is not match");
}
}
free(station_v);
}
}
}
else
// 處理 device.vap.*.station.* 的 station 部分.
// 回報處理的 vap 內有哪些 station 符合.
if(part_level == 3)
{
MCM_CCMDMSG("process station part");
MCM_CCMDMSG("device.vap.#%u.station.*", part_key[1]);
target_vap = part_key[1];
// 讀出 device.vap.#{target_vap}.station.*
snprintf(path2, sizeof(path2), "device.vap.#%u.station.*", target_vap);
fret = mcm_lulib_get_all_entry(this_lulib, path2, (void **) &station_v, &station_count);
if(fret < MCM_RCODE_PASS)
{
MCM_CCMEMSG("call mcm_lulib_get_all_entry(%s) fail", path2);
goto FREE_01;
}
if(vap_count > 0)
{
// 配置空間放置 key.
rep_list = (MCM_DTYPE_EK_TD *) malloc(sizeof(MCM_DTYPE_EK_TD) * vap_count);
if(rep_list == NULL)
{
MCM_CCMEMSG("call malloc() fail [%s]", strerror(errno));
goto FREE_02;
}
//檢查是否符合.
for(station_idx = 0; station_idx < station_count; station_idx++)
{
snprintf(path2, sizeof(path2), "device.vap.#%u.station.#%u",
target_vap, station_v[station_idx].ekey);
MCM_CCMDMSG("%s.mac_addr = " MCM_DTYPE_S_PF,
path2, station_v[station_idx].mac_addr);
MCM_CCMDMSG("%s.rule = " MCM_DTYPE_RK_PF,
path2, station_v[station_idx].rule);
if(target_rule == station_v[station_idx].rule)
{
MCM_CCMDMSG("this station is match");
rep_list[rep_count] = station_v[station_idx].ekey;
rep_count++;
}
else
{
MCM_CCMDMSG("this station is not match");
}
}
}
}
*key_list_buf = rep_list;
*key_count_buf = rep_count;
FREE_03:
if(fret < MCM_RCODE_PASS)
if(part_level == 2)
free(rep_list);
FREE_02:
if(part_level == 2)
free(vap_key);
else
if(part_level == 3)
free(station_v);
FREE_01:
#if MCM_CCMEMODE | MCM_CCMDMODE
close(dbg_console_fd);
#endif
return fret;
}
以上述的 [範例-03] 為例 :
找出符合規則類型的 station 以及所屬的 vap.
req_cmd += "&get.device.vap.*" +
"&get.device.vap.*.station.*=find_match_rule_station";
錯誤用法.
處理 "&get.device.vap.*"
device => 取出資料索引.
vap => 取出每個 device 之下的 vap 的資料索引.
處理 "&get.device.vap.*.station.*=find_match_rule_station"
device => 已經處理過, 跳過.
vap => 已經處理過, 跳過, 不執行 find_match_rule_station(part_level == 2).
station => 依據 vap 的資料筆數多次執行 find_match_rule_station(part_level == 3),
取出每個 vap 之下符合的 station 的資料索引和內容.
應該是要先找出符合的 vap, 在依據符合的 vap 去處理符合的 station.
req_cmd += "&get.device.vap.*.station.*=find_match_rule_station" +
"&get.device.vap.*";
正確用法.
處理 "&get.device.vap.*.station.*=find_match_rule_station"
device => 取出資料索引.
vap => 依據 device 的資料筆數多次執行 find_match_rule_station(part_level == 2),
先找出符合的 vap (不含資料內容).
station => 依據符合的 vap 的資料筆數多次執行 find_match_rule_station(part_level == 3),
取出符合的 vap 之下符合的 station 的資料索引和內容.
處理 "&get.device.vap.*"
device => 已經處理過, 跳過.
vap => 已經處理過 (只有資料索引), 補上這些資料的內容.
| 01. | 範例程式目錄在 mint_cm/usage/example/0305. |
| 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=0305 載入範例並編譯. |
| 05. |
web_app 是範例程式. 範例項目 :
|
| 06. |
mini_httpd 執行方法, 進入 mint_cm/run 目錄,
指令 : ./mini_httpd -C mini_httpd.conf |
| 07. | 先執行 mcm_daemon 和 mini_httpd 才可測試. |
| 08. | 瀏覽器連至 http://<server-address>/web_app_0305_index.html 就可以看到範例頁面. |
| 09. | 測試完畢不使用後, 使用 make example_del KEY=0305 將範例移除. |
| 10. |
範例程式目錄下的檔案在做完 make example_add
後會複製到真正使用的位置, 要修改做測試的話要改在複製後的.
|