20170220_jeffrey - silenceuncrio/diary GitHub Wiki
0930
review
1005
利用 ASCIIFlow
來幫 webModule
的 InitWeb()
畫個流程示意圖
+---------------------+
|InitWeb |
| LoadDefault() |
| SysParsorTextFile()|
| | +----------------------+
| InitWebIptables()+------>InitWebIptables |
| | | IPTF_JOIN_AND_NEW() |
| ApplyWebSetting() | | IP6TF_JOIN_AND_NEW()|
+---------------------+ +----------------------+
1020
繼續追 ApplyWebSetting()
webcfg.c
static int ApplyWebSetting(int flag, int index, void* pStruct, int structSize) {
sWebConfig *pCfg = (sWebConfig *)pStruct;
SysSaveBinaryFile(WEB_TMP_BIN_FILE, pCfg, sizeof(*pCfg));
if (!IsBootInitProcess()) {
LocSaveConfigTxt(WEB_TMP_CFG_FILE, pCfg);
SysCopyFile(WEB_TMP_CFG_FILE, WEB_ETC_CFG_FILE);
}
ICOS_msg_sendto(MODULE_WEB,MODULE_WEB,pCfg,sizeof(sWebConfig),ICOS_UCAST_MODULE_APPLY);
return ICOS_SUCCESS;
}
1025
追 ICOS_msg_sendto(MODULE_WEB,MODULE_WEB,pCfg,sizeof(sWebConfig),ICOS_UCAST_MODULE_APPLY)
icos_ipc.c
int ICOS_msg_sendto(int src_id, int dst_id, void *data, unsigned short data_sz, unsigned short event_id)
{
int sending_sz = 0;
int fd=-1, rc=0;
PRO_EVENT promsg, *pmsg=NULL;
pmsg = &promsg;
pmsg->src_id = src_id;
pmsg->dst_id = dst_id;
pmsg->msg_len = data_sz;
pmsg->event_id = event_id;
pmsg->usret[0] = 0;
if (data_sz>0)
memcpy(pmsg->msg, data, data_sz);
sending_sz = MSG_HEADER_LEN+data_sz;
fd=socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd>=0)
{
struct sockaddr_un to;
to.sun_family=AF_UNIX;
snprintf(to.sun_path, UNIX_PATH_MAX, "%s/%s", PRO_USOCK_PATH, USOCKNAME_EVENT);
rc=sendto(fd, pmsg, sending_sz, MSG_DONTROUTE|MSG_DONTWAIT, (struct sockaddr *)&to, sizeof(struct sockaddr_un));
close(fd);
goto END_RETURN;
}
rc = -2;
END_RETURN:
if(data_sz > MAX_MSG_LEN && pmsg)
free(pmsg);
return rc;
}
ICOS_msg_sendto()
利用了 sockets 的技術
參考 Linux Programming Interface
- 56. Sockets: Introduction
Sockets are a method of IPC that allow data to be exchanged between applications, either on the same host (computer) or on different hosts connected by a network.
使用 ICOS_msg_sendto()
的角色相當於一個 Client
那誰是 Server
的角色呢?
Server
提供了甚麼服務呢?
1110
M300 是由 icospromsg
扮演 Server
的角色
static int uscok_delete(int usock_fd)
{
...
close(usock_fd);
...
return 0;
}
static int uscok_create()
{
struct sockaddr_un skadr_un;
int svrsock;
svrsock = socket(AF_UNIX, SOCK_DGRAM, 0);
skadr_un.sun_family = AF_UNIX;
sprintf(skadr_un.sun_path, "%s/%s", PRO_USOCK_PATH, USOCKNAME_EVENT);
svrsock = socket(AF_UNIX, SOCK_DGRAM, 0);
...
bind(svrsock, (struct sockaddr*)(&skadr_un), sizeof(struct sockaddr_un));
...
return svrsock;
}
int main(int argc, char **argv)
{
...
usock_fd=uscok_create();
while (!G_loop_exit)
{
...
}//End_while
uscok_delete(usock_fd);
exit(0);
return 0;
}
1305
ariel 反應 frimware upgrade 還是有問題
ariel 表示從 browser 的 console 看到
TypeError: Cannot read property 'curr_time' of undefined
at firmware.js:68
...
我試著分析一下目前的 firmware.js
function firmwareController($route, $scope, $timeout, $location, icos, Upload, progress) {
var vm = this;
vm.progress = progress;
vm.upgrade = function(_file) {
if (_file) {
...
Upload.upload({ url: 'api/firmwareUpload', data: data })
.then(function(resp) {
vm.progress = resp.data.info;
return icos.firmware.upgrade();
})
.then(function(resp) {
...
vm.timeout_2sec();
});
}
}
var timer_2sec;
vm.timeout_2sec = function () {
timer_2sec = $timeout(2000);
timer_2sec.then(function () {
icos.firmware.progress()
.then(function(response) {
vm.progress = response.data.progress;
var busy_sec = (Date.parse(vm.progress.curr_time) - Date.parse(vm.progress.init_time))/1000
...
});
});
}
}
當 vm.progress.curr_time
不存在的狀況下的確會造成問題
1400
發現是被我的 local.conf
害的
IMAGE_INSTALL_append += "nfs-utils vim jq curl"
目前 git server 上並沒有把 jq 加上去
也就是從 git server checkout 的 code build 完並沒有 jq 這個 tool 可以用
這會導致使用 jq 的 shell script 失敗
我先把自己的 local.conf
刪掉
把目前 Local 端的修改刪除
修改 prosrc_0.1.bb
- 加上 jq
diff --git a/meta-proscend/recipes-core/prosrc/prosrc_0.1.bb b/meta-proscend/recipes-core/prosrc/prosrc_0.1.bb
old mode 100644
new mode 100755
index bce1618..14aa913
--- a/meta-proscend/recipes-core/prosrc/prosrc_0.1.bb
+++ b/meta-proscend/recipes-core/prosrc/prosrc_0.1.bb
@@ -16,7 +16,7 @@ INSANE_SKIP_${PN} += "already-stripped"
INSANE_SKIP_${PN} += "installed-vs-shipped "
# Runtime dependence
-RDEPENDS_${PN} += "ppp ppp-oe iptables iperf dnsmasq pptp-linux bridge-utils dhcp-server dhcp-client openvpn openssl openssl-conf iproute2 iproute2-tc procps socat strongswan cryptodev-module mtd-utils mtd-utils-ubifs imx-kobs tar bzip2"
+RDEPENDS_${PN} += "ppp ppp-oe iptables iperf dnsmasq pptp-linux bridge-utils dhcp-server dhcp-client openvpn openssl openssl-conf iproute2 iproute2-tc procps socat strongswan cryptodev-module mtd-utils mtd-utils-ubifs imx-kobs tar bzip2 jq"
# Build dependence
DEPENDS = "json-c rp-pppoe apr libxml2 libpcap sqlite3 xz"
1450
繼續 trace
M300 是由 icospromsg
扮演 Server
的角色
那 icospromsg
是怎麼處理來自於 ApplyWebSetting()
送來的 message 呢?
icospromsg.c
int main(int argc, char **argv)
{
int usfd = -1, maxfd=0;
int sel_ret = 0, read_bytes=0;
struct timeval timeout;
fd_set rdset;
int usock_fd;
static unsigned char *msg_buffer=NULL;
usock_fd=uscok_create();
usfd=usock_fd;
fcntl(usock_fd, F_SETFD, FD_CLOEXEC);
msg_buffer = (unsigned char *)malloc(FULL_MSG_LEN);
while (!G_loop_exit)
{
timeout.tv_sec = 1;
timeout.tv_usec = 0;
FD_ZERO(&rdset);
FD_SET(usfd, &rdset);
maxfd=usfd;
proc_FdSet(&rdset, &maxfd);
sel_ret=0;
sel_ret=select(maxfd+1, &rdset, 0, 0, &timeout);
if (sel_ret > 0)
{
if (FD_ISSET(usfd, &rdset))
{
PRO_EVENT *pmsg=NULL;
unsigned char *sp=msg_buffer;
read_bytes = recv(usfd, sp, sizeof(PRO_EVENT),MSG_DONTWAIT | MSG_NOSIGNAL);
pmsg = (PRO_EVENT*)sp;
if (pmsg->dst_id == 0) // 0: means broadcast
{
BroadcastHandle(pmsg);
}
else
{
NotifyHandle(pmsg);
}
}
}
}//End_while
}
ApplyWebSetting()
送來的 message 會觸發 icospromsg
的 NotifyHandle()
icospromsg.c
int NotifyHandle(PRO_EVENT *pmsg)
{
int res=0;
sIcosModule *pIcosModule;
pIcosModule=GetIcosModule(pmsg->dst_id);
if (pIcosModule->NotifyHandler)
{
res=pIcosModule->NotifyHandler(pmsg);
}
return res;
}
會發現 webModule
的 ApplyWebSetting()
利用 ICOS_msg_sendto()
把 message 送到 icospromsg
然後 icospromsg
只是透過 message 內含的資訊又把 webModule
的 notify_web()
叫起來做事
不過要記住 webModule
不過是個 icos library
sIcosModule webModule={
"web", // Name
InitWeb, // Init
ExitWeb, // Exit
ApplyWebSetting, // Apply
GetWebSetting, // GetSetting
SetWebSetting, // SetSetting
VerifyWebSetting, // VerifySetting
0, // GetStatus
0, // GetStatus
facotry_default_web_setting,
0,//period_ddns,
notify_web,
msgcb_web,
termcb_web,
};
要有人呼叫才會做事的
所以重點在於是誰用它來做事
再回去看 rc.local
...
/usr/sbin/icospromsg &
/usr/sbin/icosconfig bootinit
...
icospromsg
先被叫起來常駐在背景執行
icosconfig bootinit
在被執行的當下
icospromsg
已經準備好處理任何利用 ICOS_msg_sendto()
所送來的 message 了
1550
試著來解析一下 /home/log/web.log
root@Mobile Router:/home/log# cat web.log
1487572072[20170220 6:27:52] [notify_web:871]IN(E82|S44|D44)
1487572072[20170220 6:27:52] [notify_web:880]module init
1487572079[20170220 6:27:59] [notify_web:871]IN(E62|S00|D00)
1487572079[20170220 6:27:59] [notify_web:905]boot init done
1487572079[20170220 6:27:59] [web_dump:609]===init config===
1487572079[20170220 6:27:59] [web_dump:619][COM]conn_mgr=1,mod_init_done:1.
1487572079[20170220 6:27:59] [web_dump:640][CFG]mode=httpd,httpd_port=80,https_port=443,refreshperiod=2,sport=80,intf=all,secure=all,clienip=0.0.0.0
1487572079[20170220 6:27:59] [web_dump:648][DMN0]active=1,pid=-1,status=0,flag=0x0,DID0
1487572079[20170220 6:27:59] [web_dump:648][DMN1]active=1,pid=-1,status=0,flag=0x0,DID1
1487572079[20170220 6:27:59] [web_dump:653][RTI]wan4_ifname=,wan6_ifname=.
1487572079[20170220 6:27:59] [daemon_restart:756][DID0] remain IP server retry for 6 times.
1487572079[20170220 6:27:59] [create_daemon_conf:664]IN
1487572079[20170220 6:27:59] [create_daemon_conf:675]cmd_buf=>dir=/
1487572079[20170220 6:27:59] [create_daemon_conf:680]cmd_buf=>cgipat=cgi-bin/**
1487572079[20170220 6:27:59] [create_daemon_conf:685]cmd_buf=>chroot
1487572079[20170220 6:27:59] [create_daemon_conf:690]cmd_buf=>user=root
1487572079[20170220 6:27:59] [create_daemon_conf:695]cmd_buf=>max_age=0
1487572079[20170220 6:27:59] [create_daemon_conf:700]cmd_buf=>debug
1487572079[20170220 6:27:59] [daemon_restart:781][DMN]Lanch=>/usr/sbin/iweb -p 80 -d /www
1487572079[20170220 6:27:59] [daemon_restart:756][DID1] remain IP server retry for 6 times.
1487572079[20170220 6:27:59] [web_dump:609]===cfg not allowed===
1487572079[20170220 6:27:59] [web_dump:640][CFG]mode=httpd,httpd_port=80,https_port=443,refreshperiod=2,sport=80,intf=all,secure=all,clienip=0.0.0.0
1487572079[20170220 6:27:59] [web_dump:648][DMN0]active=1,pid=775,status=1,flag=0x0,DID0
1487572079[20170220 6:27:59] [web_dump:648][DMN1]active=1,pid=-1,status=0,flag=0x1,DID1
1487572079[20170220 6:27:59] [web_dump:609]===After daemon restart===
1487572079[20170220 6:27:59] [web_dump:619][COM]conn_mgr=1,mod_init_done:1.
1487572079[20170220 6:27:59] [web_dump:640][CFG]mode=httpd,httpd_port=80,https_port=443,refreshperiod=2,sport=80,intf=all,secure=all,clienip=0.0.0.0
1487572079[20170220 6:27:59] [web_dump:648][DMN0]active=1,pid=775,status=1,flag=0x0,DID0
1487572079[20170220 6:27:59] [web_dump:648][DMN1]active=1,pid=-1,status=0,flag=0x0,DID1
1487572079[20170220 6:27:59] [web_dump:653][RTI]wan4_ifname=,wan6_ifname=.
1487572079[20170220 6:27:59] [notify_web:871]IN(E50|S59|D00)
1487572082[20170220 6:28:2] [msgcb_web:1155]IN(DID0,pid 775)
<--
Icos_user_root.session_ttl: 300 sec
Icos_user_root.user: root
Icos_user_root.pass: $1$$2Dg0uARUa9gcTJ9I5/iKb/
Starting iweb on port 80, serving /www
-->
1487572082[20170220 6:28:2] [notify_web:871]IN(E53|S50|D00)
1487572082[20170220 6:28:2] [notify_web:871]IN(E02|S56|D00)
1487572083[20170220 6:28:3] [notify_web:871]IN(E01|S56|D00)
1487572084[20170220 6:28:4] [notify_web:871]IN(E43|S35|D00)
直接從第一行看起 1487572072[20170220 6:27:52] [notify_web:871]IN(E82|S44|D44)
這是由目前 webcfg.c
的 第 871 行的 WEB_INFO
所打印的
#define WEB_INFO(FMT, ARG...) IPC_filelog_v2(WEB_LOG,IPCF_LOGMAX, __FUNCTION__, __LINE__,IPCFv2_SHOW_TIME, FMT, ##ARG)
static int notify_web(PRO_EVENT *pevent)
{
...
WEB_INFO("IN(E%02d|S%02d|D%02d)\n",pevent->event_id,pevent->src_id,pevent->dst_id);
...
}
來看 1487572072[20170220 6:27:52] [notify_web:871]IN(E82|S44|D44)
裡的 (E82|S44|D44)
先看 E82
- event_id = 82
定義在 icos_shm.h
// All Events ID
typedef enum
{
// COMMON_GRP
ICOS_CHG_WPROTO = 1,
ICOS_CHG_CONN_TYPE,
//SYSTEM_GRP
ICOS_AC_ADAPTER=10,
ICOS_WAN_SWITCH, // Switch Router / Bridge mode
ICOS_SYSTEM_SHUTDOWN,
ICOS_SYSTEM_REBOOT,
ICOS_IPV6_FUNCTION,
//LTE_GRP
ICOS_WLTE_PPP_UP=20,
ICOS_WLTE_PPP_DOWN,
//WWIFI_GRP
ICOS_WWIFI_LOST_ASSOCIATION=30, //lost association then wifi just stop
ICOS_WWIFI_GOT_CONNECTION,
ICOS_WWIFI_ENABLE,
ICOS_WWIFI_DISABLE,
ICOS_WWIFI_REAUTH,
//ETHERNET_GRP: Please with interface name and length as argument
ICOS_WETH_LINK_DOWN=40, // Wan cable plug out
ICOS_WETH_LINK_UP, // Wan cable plug in
ICOS_ETH_LINK_DOWN, // Lan cable plug out
ICOS_ETH_LINK_UP, // Lan cable plug in
ICOS_WETH_PPP_UP,
ICOS_WETH_PPP_DOWN,
// IP_UPDATE_GRP
ICOS_LAN_IP_UPDATE=50,
ICOS_WAN_IP_UPDATE,
ICOS_WAN_LOST_CONNECTION,
ICOS_LAN6_IP_UPDATE,
ICOS_WAN6_IP_UPDATE,
ICOS_WAN6_LOST_CONNECTION,
ICOS_WAN_CFG_UPDATE, //For dns decision wan is static or dynamic IP, John20160406
ICOS_WAN_GATEWAY_UPDATE,
ICOS_WAN6_GATEWAY_UPDATE,
// LAUNCH PROCESS
ICOS_LAUNCH_PROCESS=60, // launch process
ICOS_KILL_PROCESS, // kill process
ICOS_BOOTINIT_DONE, // icos module init done
//=====NOT broadcast event======
// MODULE ACTION
ICOS_UCAST_MODULE_INIT=80, //Module Init indication; NOT broadcast event
ICOS_UCAST_MODULE_EXIT, // 81:Module Exit indication; NOT broadcast event
ICOS_UCAST_MODULE_APPLY, // 82:Module Apply indication; NOT broadcast event
ICOS_UCAST_CHG_WPROTO, // 83:Web UI -> connmgr to change active wan protocol
ICOS_UCAST_JSON_DATA, // 84:JSON data unicast notification
ICOS_UCAST_WLTE_MODEM_READ_DONE, // 85:read_modem -> lte module
ICOS_UCAST_WLTE_PPPD_LAUNCH, // 86:lte connect thread -> lte module
ICOS_UCAST_WLTE_CONNECT_ACTION, // 87:lte module only
ICOS_UCAST_NWST_EVT_UPDATE, // 88:netmon -> netmond
ICOS_UCAST_NWST_CFG_UPDATE, // 89:netmon -> netmond
ICOS_UCAST_DNS_CFG_UPDATE, // 90:dns_ext6 -> wan static
ICOS_UCAST_WLTE_CHG_NETMODE, // 91:lte_t -> lte (1: LTE only; 2: 3G only; 3: GSM only; others: AUTO
ICOS_UCAST_WLTE_DISCONNECT, // 92:lte_t -> lte (test disconnect and then automatically reconnect)
} ICOS_EVENT_ID_E;
E82
表示 event_id = ICOS_UCAST_MODULE_APPLY
再看 S44
- src_id = 44
icos_module.h
// *********************************************************************************
// * Module ID
// *********************************************************************************
enum
{
...
MODULE_WEB,
MODULE_WIFI, // 45
...
MODULE_MAX, // Ariel: MAX has to be the last items
};
S44
表示 src_id = MODULE_WEB
再看 D44
- dst_id = 44
D44
表示 dst_id = MODULE_WEB
簡單說第一行 1487572072[20170220 6:27:52] [notify_web:871]IN(E82|S44|D44)
表示
- event_id =
ICOS_UCAST_MODULE_APPLY
- src_id =
MODULE_WEB
- dst_id =
MODULE_WEB