Commit a615faf9 authored by 陈伟灿's avatar 陈伟灿

Merge branch 'yjq' into 'master'

Yjq

See merge request chenweican/k-sdk!11
parents d6172530 2a352fcf
1. 版本:tiny-curl-7.72.0
download:https://curl.haxx.se/tiny/
2. 编译so选项:./configure --disable-dict --disable-ftp --disable-imap --disable-ldap --disable-file --disable-gopher --disable-imap --disable-ldaps --disable-pop3 --disable-proxy --disable-rtsp --disable-smtp --disable-telnet --disable-tftp --disable-zlib --without-ca-bundle --without-gnutls --without-libidn --without-librtmp --without-libssh2 --without-nss --without-zlib
3. 交叉编译选项 9531: ./configure --disable-dict --disable-ftp --disable-imap --disable-ldap --disable-file --disable-gopher --disable-imap --disable-ldaps --disable-pop3 --disable-proxy --disable-rtsp --disable-smtp --disable-telnet --disable-tftp --disable-zlib --without-ca-bundle --without-gnutls --without-libidn --without-librtmp --without-libssh2 --without-nss --without-zlib --host=mips-openwrt-linux CC=mips-openwrt-linux-gcc --prefix=$PWD/__install
4. 编译example:gcc -o example_curl example_curl.c -L. -lcurl_ubuntu
1. 版本:tiny-curl-7.72.0
download:https://curl.haxx.se/tiny/
2. 编译so选项:./configure --disable-dict --disable-ftp --disable-imap --disable-ldap --disable-file --disable-gopher --disable-imap --disable-ldaps --disable-pop3 --disable-proxy --disable-rtsp --disable-smtp --disable-telnet --disable-tftp --disable-zlib --without-ca-bundle --without-gnutls --without-libidn --without-librtmp --without-libssh2 --without-nss --without-zlib
3. 交叉编译选项 9531: ./configure --disable-dict --disable-ftp --disable-imap --disable-ldap --disable-file --disable-gopher --disable-imap --disable-ldaps --disable-pop3 --disable-proxy --disable-rtsp --disable-smtp --disable-telnet --disable-tftp --disable-zlib --without-ca-bundle --without-gnutls --without-libidn --without-librtmp --without-libssh2 --without-nss --without-zlib --host=mips-openwrt-linux CC=mips-openwrt-linux-gcc --prefix=$PWD/__install
4. 编译example:gcc -o example_curl example_curl.c -L. -lcurl_ubuntu
#include "include/curl.h"
size_t kk_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
return fwrite(ptr, size, nmemb, stream);
}
int kk_progress_func(char *progress_data,
double t, /* dltotal */
double d, /* dlnow */
double ultotal,
double ulnow)
{
printf("%s %g / %g (%g %%)\n", progress_data, d, t, d*100.0/t);
return 0;
}
int main(int argc, char **argv)
{
CURL *curl;
CURLcode res;
FILE *outfile;
char *url = argv[1];//"https://pics0.baidu.com/feed/6609c93d70cf3bc7fecc2bfb9d12faa6cc112af6.jpeg?token=517920fbf7c2fef6ff3ab5ff55bbd8d7";
char *progress_data = "* ";
if (argc < 3){
printf("==inpunt params error, Usage:example_curl <url> <fileName> \n");
return 0;
}
curl = curl_easy_init();
if(curl)
{
outfile = fopen(argv[2], "wb");//fopen("test.jpg", "wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, kk_write_func);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, kk_progress_func);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progress_data);
res = curl_easy_perform(curl);
fclose(outfile);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
#include "include/curl.h"
size_t kk_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
return fwrite(ptr, size, nmemb, stream);
}
int kk_progress_func(char *progress_data,
double t, /* dltotal */
double d, /* dlnow */
double ultotal,
double ulnow)
{
printf("%s %g / %g (%g %%)\n", progress_data, d, t, d*100.0/t);
return 0;
}
int main(int argc, char **argv)
{
CURL *curl;
CURLcode res;
FILE *outfile;
char *url = argv[1];//"https://pics0.baidu.com/feed/6609c93d70cf3bc7fecc2bfb9d12faa6cc112af6.jpeg?token=517920fbf7c2fef6ff3ab5ff55bbd8d7";
char *progress_data = "* ";
if (argc < 3){
printf("==inpunt params error, Usage:example_curl <url> <fileName> \n");
return 0;
}
curl = curl_easy_init();
if(curl)
{
outfile = fopen(argv[2], "wb");//fopen("test.jpg", "wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, kk_write_func);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, kk_progress_func);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progress_data);
res = curl_easy_perform(curl);
fclose(outfile);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
......@@ -141,7 +141,6 @@ int kk_property_db_insert(const char *deviceCode,const char *identifier,kk_tsl_d
char *zErrMsg = 0;
kk_property_db_ctx_t *ctx = _kk_property_db_get_ctx();
if(_kk_check_property_exist(deviceCode,identifier) == 1)
{
WARNING_PRINT("[%s][%d] DATA ALREADY EXIST!!!\n",__FUNCTION__,__LINE__);
......
......@@ -8,7 +8,3 @@
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"zclOnOff"
}
]
}
\ No newline at end of file
#ifndef __KK_TSL_PROPERTY_REPORT_H
#define __KK_TSL_PROPERTY_REPORT_H
#include "kk_zb_com.h"
#include "kk_msg_report.h"
typedef enum{
tsl_rpt_success = 0,
tsl_rpt_err = -1,
tsl_rpt_invaild_val = -2,
tsl_rpt_invaild_len = -3,
tsl_rpt_invaild_type = -4,
}kk_tsl_rpt_status;
void kk_tsl_report_attribute(EmberEUI64 eui64,
uint8_t EP,
EmberAfClusterId clusterId,
EmberAfAttributeId attributeId,
uint8_t dataType,
uint8_t len,
uint8_t *data);
int kk_tsl_report_global_onoff(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_windowCovering_mode(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_windowCovering_position(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_ias_zoneStatus(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_metering_summationDelivered(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_global_Level(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_temperature_measure(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_illuminance_measure(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_local_temperature(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_OccupiedHeatingSetpoint(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_Formaldehyde(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_PM2_5(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_CO2(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_colorControl_Brightness(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_colorControl_RGB(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
#endif
#ifndef __KK_TSL_PROPERTY_REPORT_H
#define __KK_TSL_PROPERTY_REPORT_H
#include "kk_zb_com.h"
#include "kk_msg_report.h"
typedef enum{
tsl_rpt_success = 0,
tsl_rpt_err = -1,
tsl_rpt_invaild_val = -2,
tsl_rpt_invaild_len = -3,
tsl_rpt_invaild_type = -4,
}kk_tsl_rpt_status;
void kk_tsl_report_attribute(EmberEUI64 eui64,
uint8_t EP,
EmberAfClusterId clusterId,
EmberAfAttributeId attributeId,
uint8_t dataType,
uint8_t len,
uint8_t *data);
int kk_tsl_report_global_onoff(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_windowCovering_mode(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_windowCovering_position(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_ias_zoneStatus(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_metering_summationDelivered(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_global_Level(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_temperature_measure(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_illuminance_measure(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_local_temperature(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_OccupiedHeatingSetpoint(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_Formaldehyde(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_PM2_5(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_CO2(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_colorControl_Brightness(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_colorControl_RGB(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
#endif
......@@ -40,6 +40,96 @@ kk_rpc_report_api_s kk_rpc_report_api[];
uint8_t kk_get_rpc_set_api_size(void );
uint8_t kk_get_rpc_report_api_size(void );
typedef enum{
EnrollResponseCode_Success = 0x00,
EnrollResponseCode_NoSupported = 0x01,
EnrollResponseCode_NoEnrollPermit = 0x02,
EnrollResponseCode_TooManyZones = 0x03,
}EnrollResponseCode;
typedef enum{
ArmMode_Disarm = 0x00,
ArmMode_ArmDayOrHomeZonesOnly = 0x01,
ArmMode_ArmNightOrSleepZonesOnly = 0x02,
ArmMode_ArmAllZones = 0x03,
}ArmMode;
typedef enum{
ArmNotification_AllZonesDisarmed = 0x01,
ArmNotification_OnlyDayOrHomeZonesArmed = 0x02,
ArmNotification_OnlyNightOrSleepZonesArmed = 0x03,
ArmNotification_AllZonesArmed = 0x04,
ArmNotification_InvalidArmOrDisarmCode = 0x05,
ArmNotification_NotReadyToArm = 0x06,
ArmNotification_AlreadyDisarmed
}ArmNotification;
typedef enum{
PanelStatus_PanelDisarmedAndReadyToArm = 0x00,
PanelStatus_ArmedStay = 0x01,
PanelStatus_ArmedNight = 0x02,
PanelStatus_ArmedAway = 0x03,
PanelStatus_ExitDelay = 0x04,
PanelStatus_EntryDelay = 0x05,
PanelStatus_NotReadyToArm = 0x06,
PanelStatus_InAlarm = 0x07,
PanelStatus_ArmingStay = 0x08,
PanelStatus_ArmingNight = 0x09,
PanelStatus_ArmingAway = 0x0a,
}PanelStatus;
typedef enum{
AlarmStatus_NoAlarm = 0x00,
AlarmStatus_Burglar = 0x01,
AlarmStatus_Fire = 0x02,
AlarmStatus_Emergency = 0x03,
AlarmStatus_PolicePanic = 0x04,
AlarmStatus_FirePanic = 0x05,
AlarmStatus_EmergencyPanic = 0x06,
}AlarmStatus;
typedef enum{
BypassResult_ZoneBypassed = 0x00,
BypassResult_ZoneNotBypassed = 0x01,
BypassResult_NotAllowed = 0x02,
BypassResult_InvalidZoneID = 0x03,
BypassResult_UnknownZoneID = 0x04,
BypassResult_InvalidArmOrDisarmCode = 0x05,
}BypassResult;
typedef struct
{
uint8_t zoneId;
uint16_t zoneStatus;
}ZoneStatus_s;
typedef enum{
WarningModes_Stop = 0x00,
WarningModes_Burglar = 0x01,
WarningModes_Fire = 0x02,
WarningModes_Emergency = 0x03,
WarningModes_PolicePanic = 0x04,
WarningModes_FirePanic = 0x05,
WarningModes_EmergencyPanic = 0x06,
}WarningModes;
typedef enum{
StrobeField_NoStrobe = 0x00,
StrobeField_UseStrobe = 0x01,
}StrobeField;
typedef enum{
SirenLevel_LowLevelSound = 0x00,
SirenLevel_MediumLevelSound = 0x01,
SirenLevel_HighLevelSound = 0x02,
SirenLevel_VeryHighLevelSound = 0x03,
}SirenLevel;
typedef enum{
StrobeLevel_LowLevelSound = 0x00,
StrobeLevel_MediumLevelSound = 0x01,
StrobeLevel_HighLevelSound = 0x02,
StrobeLevel_VeryHighLevelSound = 0x03,
}StrobeLevel;
typedef enum{
SquawkModeField_Arm = 0x00,
SquawkModeField_Disarmed = 0x01,
}SquawkModeField;
EmberStatus kk_network_leave(void);
......@@ -418,4 +508,115 @@ EmberStatus zclThermostat_GetRelayStatusLog(uint16_t node,
uint8_t ep);
//IAS
EmberStatus arm_command(uint16_t node,
uint8_t ep,
ArmMode mode,
char* code,
uint8_t id);
EmberStatus bypass_command(uint16_t node,
uint8_t ep,
uint8_t num,
uint8_t *id,
char* code);
EmberStatus emergency_command(uint16_t node,
uint8_t ep);
EmberStatus fire_command(uint16_t node,
uint8_t ep);
EmberStatus panic_command(uint16_t node,
uint8_t ep);
EmberStatus get_zone_id_command(uint16_t node,
uint8_t ep);
EmberStatus get_zone_information_command(uint16_t node,
uint8_t ep,
uint8_t id);
EmberStatus get_panel_status_command(uint16_t node,
uint8_t ep);
EmberStatus get_bypassed_zone_list_command(uint16_t node,
uint8_t ep);
EmberStatus get_zone_status_command(uint16_t node,
uint8_t ep,
uint8_t statrId,
uint8_t maxNum,
bool flag,
uint16_t mask);
EmberStatus arm_response(uint16_t node,
uint8_t ep,
ArmNotification arm);
EmberStatus get_zone_id_map_response(uint16_t node,
uint8_t ep,
uint16_t* map);//16
EmberStatus get_zone_information_response(uint16_t node,
uint8_t ep,
uint8_t id,
uint16_t type,
uint8_t* ieee,
char* label);
EmberStatus zone_status_changed(uint16_t node,
uint8_t ep,
uint8_t id,
uint16_t zonestatus,
uint8_t audible,
char* label);
EmberStatus panel_status_changed(uint16_t node,
uint8_t ep,
PanelStatus panel,
uint8_t remain,
uint8_t audible,
AlarmStatus alarm);
EmberStatus get_panel_status_response(uint16_t node,
uint8_t ep,
PanelStatus panel,
uint8_t remain,
uint8_t audible,
AlarmStatus alarm);
EmberStatus set_bypassed_zone_list(uint16_t node,
uint8_t ep,
uint8_t num,
uint8_t* id);
EmberStatus bypass_response(uint16_t node,
uint8_t ep,
uint8_t num,
BypassResult* id);
EmberStatus get_zone_status_response(uint16_t node,
uint8_t ep,
bool complete,
uint8_t num,
ZoneStatus_s**ZoneStatus);
EmberStatus start_warning(uint16_t node,
uint8_t ep,
WarningModes mode,
StrobeField strobe,
SirenLevel siren,
uint16_t duration,
uint8_t cycle,
StrobeLevel level);
EmberStatus squawk_command(uint16_t node,
uint8_t ep,
WarningModes mode,
StrobeField strobe,
SquawkModeField squawk);
#endif
#!/bin/sh
#判断进程是否存在,如果不存在就启动它
while true
do
sleep 30
PIDS=`ps|grep kk_midware |grep -v grep | awk '{print $1}'`
if [ "$PIDS" != "" ]; then
echo "kk_midware is runing!"
else
/home/kk/kk_midware >/dev/null 2>&1 &
#运行进程
fi
sleep 30
PIDS=`ps|grep kcloud |grep -v grep | awk '{print $1}'`
if [ "$PIDS" != "" ]; then
echo "kcloud is runing!"
else
/home/kk/kcloud >/dev/null 2>&1 &
#运行进程
fi
done
#!/bin/sh
#判断进程是否存在,如果不存在就启动它
while true
do
sleep 30
PIDS=`ps|grep kk_midware |grep -v grep | awk '{print $1}'`
if [ "$PIDS" != "" ]; then
echo "kk_midware is runing!"
else
/home/kk/kk_midware >/dev/null 2>&1 &
#运行进程
fi
sleep 30
PIDS=`ps|grep kcloud |grep -v grep | awk '{print $1}'`
if [ "$PIDS" != "" ]; then
echo "kcloud is runing!"
else
/home/kk/kcloud >/dev/null 2>&1 &
#运行进程
fi
done
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
nanomsg_File="/home/kk/lib/libnanomsg.so.5"
ev_File="/home/kk/lib/libev.so.4"
cd /sbin/
insmod /sbin/ssd1306-revision.ko
/sbin/oled >/dev/null 2>&1 &
sleep 1
export LD_LIBRARY_PATH=/home/kk/lib
cd /home/kk/lib
if [ ! -f "$nanomsg_File" ]; then
ln libnanomsg.so libnanomsg.so.5
fi
if [ ! -f "$ev_File" ]; then
ln libev.so libev.so.4
fi
CCU_ID=`cat /etc/dropbear/accessory/hj/hj_ccuid`
/sbin/logread -f -r 120.55.149.201 514 -p /var/run/logread.cloud_log.pid -u -h $CCU_ID >/dev/null 2>&1 &
/sbin/logread -f -e "ccu_err_info" -F /etc/dropbear/accessory/hj/err.log -p /var/run/logread.err_log.pid -S 512 >/dev/null 2>&1 &
sleep 1
/home/kk/run.sh >/dev/null 2>&1 &
sleep 10
/home/kk/process_check.sh >/dev/null 2>&1 &
cd /sbin
/sbin/logd-check.sh >/dev/null 2>&1 &
sleep 1
ntpd -n -q -d -p stdtime.gov.hk &
exit 0
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
nanomsg_File="/home/kk/lib/libnanomsg.so.5"
ev_File="/home/kk/lib/libev.so.4"
cd /sbin/
insmod /sbin/ssd1306-revision.ko
/sbin/oled >/dev/null 2>&1 &
sleep 1
export LD_LIBRARY_PATH=/home/kk/lib
cd /home/kk/lib
if [ ! -f "$nanomsg_File" ]; then
ln libnanomsg.so libnanomsg.so.5
fi
if [ ! -f "$ev_File" ]; then
ln libev.so libev.so.4
fi
CCU_ID=`cat /etc/dropbear/accessory/hj/hj_ccuid`
/sbin/logread -f -r 120.55.149.201 514 -p /var/run/logread.cloud_log.pid -u -h $CCU_ID >/dev/null 2>&1 &
/sbin/logread -f -e "ccu_err_info" -F /etc/dropbear/accessory/hj/err.log -p /var/run/logread.err_log.pid -S 512 >/dev/null 2>&1 &
sleep 1
/home/kk/run.sh >/dev/null 2>&1 &
sleep 10
/home/kk/process_check.sh >/dev/null 2>&1 &
cd /sbin
/sbin/logd-check.sh >/dev/null 2>&1 &
sleep 1
ntpd -n -q -d -p stdtime.gov.hk &
exit 0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment