diff --git a/index.php b/index.php
new file mode 100644
index 0000000..b863a57
--- /dev/null
+++ b/index.php
@@ -0,0 +1,102 @@
+", "practice");
+
+ if (mysqli_connect_errno()) {
+ //printf("Connect failed: %s\n", mysqli_connect_error());
+ exit();
+ }
+
+ //printf("#connect successfully
\n");
+
+ if(isset($_GET["inst"]))
+ {
+ $serial = "\"".$_GET["inst"]."\"";
+ if( !(isset($_GET["code"])))
+ {
+ //echo "not API
";
+ $query = "SELECT OpCode FROM status WHERE SerialNo = $serial";
+ //echo "#query
=>
$query
";
+
+ if ($result = mysqli_query($link, $query))
+ {
+ if ($row = mysqli_fetch_row($result))
+ {
+ $service_code = "\"$row[0]\"";
+ echo "service_code:$row[0]";
+
+ //echo "
insert service_code to log
";
+ $query = "INSERT INTO log(Time,SerialNo,OpCode) VALUES (\"$time\", $serial, $service_code)";
+ //echo "#query
=>
$query
";
+ mysqli_query($link, $query);
+ //printf("Insert New Record sucessfully
");
+ }
+ else
+ {
+ //echo "
insert wrong service_code to log
";
+ $query = "INSERT INTO log(Time,SerialNo,OpCode,msg) VALUES (\"$time\", $serial, \"\",\"wrong serial\")";
+ mysqli_query($link, $query);
+
+ //printf("Insert New wrong record sucessfully
");
+ }
+ mysqli_free_result($result);
+ mysqli_free_result($row);
+ }
+ }
+ else
+ {
+ //echo "is API
";
+ $service_code = "\"".$_GET["code"]."\"";
+
+ if($service_code == "\"666\"")
+ {
+ //echo "
insert API's service code to log
";
+ $query = "INSERT INTO log(Time,SerialNo,OpCode) VALUES (\"$time\", $serial, $service_code)";
+ mysqli_query($link, $query);
+ //printf("Insert into log sucessfully
");
+
+ //printf("update status to 666
");
+ $query="UPDATE status SET OpCode = $service_code WHERE SerialNo = $serial";
+ mysqli_query($link, $query);
+ //printf("update successfully.
Affected rows (UPDATE): %d
", mysqli_affected_rows($link));
+ }
+ else if($service_code == "\"400\"")
+ {
+ if(isset($_GET["msg"]))
+ {
+ $msg="\"".$_GET["msg"]."\"";
+ $query = "INSERT INTO log(Time,SerialNo,OpCode,msg) VALUES (\"$time\", $serial, $service_code,$msg)";
+ mysqli_query($link, $query);
+ //printf("Insert 400 sucessfully
");
+
+ //printf("update status to 000
");
+ $query="UPDATE status SET OpCode = \"000\" WHERE SerialNo = $serial";
+ mysqli_query($link, $query);
+ //printf("update successfully.
Affected rows (UPDATE): %d
", mysqli_affected_rows($link));
+ }
+ }
+ else if($service_code == "\"777\"")
+ {
+ //echo "
insert API's service code to log
";
+ $query = "INSERT INTO log(Time,SerialNo,OpCode) VALUES (\"$time\", $serial, $service_code)";
+ mysqli_query($link, $query);
+ //printf("Insert into log sucessfully
");
+
+ //printf("update status to 000
");
+ $query="UPDATE status SET OpCode = \"000\" WHERE SerialNo = $serial";
+ mysqli_query($link, $query);
+ //printf("update successfully.
Affected rows (UPDATE): %d
", mysqli_affected_rows($link));
+ }
+
+ }
+ }
+ else
+ {
+ //printf("no serial");
+ }
+
+mysqli_close($link);
+?>
\ No newline at end of file
diff --git a/serviceApi.c b/serviceApi.c
new file mode 100644
index 0000000..806724d
--- /dev/null
+++ b/serviceApi.c
@@ -0,0 +1,515 @@
+#include
+#include //memcmp 要 include 的 header
+#include
+#include //getpid()
+#include
+#include
+#include
+#include //sockaddr_in
+#include //socket()
+
+#define PORT 80 // Client 所要連線的 port
+#define MAXDATASIZE 500 //最大可收的 bytes 大小
+
+char ip[50];
+char port[50];
+char user[50];
+char password[50];
+char folder[50];
+char command[500];
+char serial[50];
+int checkT = 0, checkR = 0; //0為complete; -1回傳開檔失敗; -2回傳 傳檔/收檔失敗 的錯誤 Message
+int errorCountR = 0, errorCountT = 0;
+
+void readConfig() //用來存取 ip, port, password 等等變數的 function
+{
+ FILE *fp;
+ fp = fopen("service.cfg", "r"); //開檔,讀取service.cfg的檔案
+ if(fp == NULL)
+ printf("open failure\n");
+ else
+ {
+ while(1)
+ {
+ fgets(command, 500, fp); //從fp中一次讀取一行指令(500字元)到common中
+
+ if(feof(fp)) //如讀到底則 Break
+ {
+ break;
+ }
+ else
+ {
+ char check[500];
+ sscanf(command, "%s %*s", check); //從command中讀取前面的字元存到 check 中,後面的字元省略
+
+ if(memcmp(check, "IP", 2) == 0) //如 (check == "IP") 則從 command 中讀取後面的字元存到 ip 變數中,前面的字元省略
+ {
+ sscanf(command, "%*s %s", ip);
+ }
+ else if(memcmp(check, "PORT", 4) == 0)
+ {
+ sscanf(command, "%*s %s", port);
+ }
+ else if(memcmp(check, "PASSWORD", 8) == 0)
+ {
+ sscanf(command, "%*s %s", password);
+ }
+ else if(memcmp(check, "USER", 4) == 0)
+ {
+ sscanf(command, "%*s %s", user);
+ }
+ else if(memcmp(check, "FOLDER", 6) == 0)
+ {
+ sscanf(command, "%*s %s", folder);
+ }
+ }
+ }
+ fclose(fp);
+ }
+}
+
+/*void readSerialNo() //用來讀取序號用的 function
+{
+ FILE *fp2;
+ fp2 = fopen("/proc/cpuinfo", "r");
+
+ if(fp2 == NULL)
+ {
+ printf("open failure\n");
+ }
+ else
+ {
+ while(1)
+ {
+ fgets(command, 500, fp2);
+ if(feof(fp2))
+ {
+ break;
+ }
+ else
+ {
+ char check[500];
+ sscanf(command, "%s %*[]", check);
+ if(memcmp(check, "Serial", 6) == 0)
+ {
+ sscanf(command, "%*[^:] %*s %s", serial); //從command中,前面到:為止都省略掉,再省略一個空格,讀取最後一個字元存到serial
+ //printf("%s\n", serial);
+ sprintf(serial, "%s", serial); //把serial存成指定格式(%s)
+ //printf("%d\n", strlen(serial)); //測試serial有幾個字元
+ }
+ }
+ }
+ fclose(fp2); //記得關檔
+ }
+}*/
+
+void FileRevOk() //查看是否成功下載檔案,如成功跳出"file recv successfully"
+{ //如失敗跳出 "file not recv"
+ char buf[500];
+ FILE *pp;
+
+ printf("Befor receive, 以上正常\n");
+
+ if((pp = popen(command, "r")) == NULL)
+ {
+ printf("popen() error!\n");
+ checkR = -1;
+ return; //回傳 not found
+ }
+ else
+ {
+ while(fgets(buf, sizeof(buf), pp))
+ {
+ //printf("%s", buf);
+ if(memcmp(buf, "file recv ok", 12) == 0)
+ {
+ printf("file recv successfully\n");
+ pclose(pp);
+ checkR = 0;
+ return;
+ }
+ }
+
+ pclose(pp);
+ printf("file not recv\n");
+ checkR = -2;
+ return;
+ }
+}
+
+void FileTransferOk()
+{
+ char buf[500];
+ FILE *pp;
+
+ puts("Befor transfer, 以上正常\n");
+
+ if((pp = popen(command, "r")) == NULL)
+ {
+ printf("popen() error!\n");
+ checkT = -1;
+ return;
+ }
+ else
+ {
+ while(fgets(buf, sizeof(buf), pp))
+ {
+ if(memcmp(buf, "Transfer OK.", 12) == 0)
+ {
+ printf("file transfer successfully\n");
+ pclose(pp);
+ checkT = 0;
+ return;
+ }
+ }
+
+ pclose(pp);
+ printf("file not transfer\n");
+ checkT = -2;
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// tcpConnect //
+// //
+////////////////////////////////////////////////////////////////////////////////
+
+int tcpConnect(int return_code, char msg[50])
+{
+ int sockfd; //socket的描述
+ int i;
+ int numbytes;
+ int service_code;
+ char buf[MAXDATASIZE];
+ struct hostent *host;
+ struct sockaddr_in info;
+ struct timeval tv;
+
+ sprintf(buf, "GET /index.php?inst=%s&&code=%d&&msg=%s HTTP/1.1\r\n", serial, return_code, msg);
+ i = strlen(buf);
+
+ if(return_code == 400)
+ {
+ //printf("Failure, Error message : %s\n", message);
+ sprintf(&buf[i], "Host: %s\r\nConnection: Failure\r\n\r\n\r\n\0\0\0\0\0\0\0", ip);
+ }
+ else if(return_code == 777)
+ {
+ //printf("complete\n");
+ sprintf(&buf[i], "Host: %s\r\nConnection: Complete\r\n\r\n\r\n\0\0\0\0\0\0\0", ip);
+ }
+ else if(return_code == 666)
+ {
+ //printf("under processing\n");
+ sprintf(&buf[i], "Host: %s\r\nConnection: Keep-Alive\r\n\r\n\r\n\0\0\0\0\0\0\0", ip);
+ }
+ else
+ {
+ puts("your return_code is wrong.\n");
+ }
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0); //socket的描述浮
+ if(sockfd == -1)
+ {
+ perror("socket");
+ exit(1);
+ }
+
+
+ bzero(&info, sizeof(info)); //初始化,將struct涵蓋的bits設為0
+ info.sin_family = AF_INET; //使用IPv4協定的地址
+ info.sin_addr.s_addr = inet_addr(ip); //IP address, inet_addr()可將字串IP變成 binary's IP
+ //info.sin_addr.s_addr = inet_addr("10.0.0.49");//先指向自己的 IP 練習, 可以把防火牆打開測試connected的timeout
+ info.sin_port = htons(PORT); //埠號,Host TO Network Short integer的縮寫,它將本機端的字節序(endian)轉換成了網路端的字節序
+ //printf("test %x\n", info.sin_addr.s_addr);
+
+ //socket的連線
+ //沒有timeout版本的connect
+ if((connect(sockfd, (struct sockaddr *)&info, sizeof(info))) == -1)
+ {
+ perror("connect");
+ exit(1);
+ }
+ printf("connect successfully\n");
+ //沒有timeout版本的connect
+
+
+ //有timeout 版本的connect
+ /*int res = connect(sockfd, (struct sockaddr *)&info, sizeof(info));
+ if(res < 0)
+ {
+ if(errno == EINPROGRESS) //connect 還在進行中
+ {
+ perror("EINPROGRESS in connect");
+
+ fd_set myset;
+ do
+ {
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+ FD_ZERO(&myset);
+ FD_SET(sockfd, &myset);
+ res = select(sockfd+1, NULL, &myset, NULL, &tv);
+ if(res < 0 && errno != EINTR)
+ {
+ perror("connect error");
+ exit(1);
+ }
+ else if(res >0)
+ {
+ socklen_t len;
+ int valopt;
+
+ len = sizeof(int);
+ if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &len) < 0) //getsockopt can determine if the socket is connected (=0, connected)
+ {
+ perror("Error in getsockopt()");
+ exit(1);
+ }
+
+ if(valopt)
+ {
+ perror("Error in delay");
+ exit(1);
+ }
+ break;
+ }
+ else
+ {
+ perror("Timeout");
+ exit(1);
+ }
+ }while(1);
+ }
+ else
+ {
+ perror("connect error");
+ exit(1);
+ }
+ }//有timeout版的connect
+ */
+
+ //傳送資料(send a message on a socket),如正確 send 會回傳實際送出的 Byte 數
+ if((send(sockfd, buf, sizeof(buf), 0)) == -1)
+ {
+ perror("send");
+ exit(1);
+ }
+ //printf("send:\n%s\n", buf);
+ printf("After the send function \n\n");
+
+
+ //接收資料,如正確 recv 會回傳實際讀到並寫入到 buffer 的 Byte 數
+ numbytes = recv(sockfd, buf, sizeof(buf), 0);
+ //printf("numbytes = %d\n", numbytes);
+ if(numbytes == -1)
+ {
+ perror("recv");
+ exit(1);
+ }
+
+ close(sockfd);
+
+ buf[numbytes] = '\0';
+ printf("Received in pid = %d, text = %s \n", getpid(), buf);
+
+ return 0;
+}
+
+int updateFirmware()
+{
+ int sockfd; //socket的描述
+ int i;
+ int numbytes;
+ int service_code;
+ char buf[12] = {1,2,0,0,0,6,1,6,0,0x70,1,0x81};
+ struct hostent *host;
+ struct sockaddr_in info;
+
+ i = strlen(buf);
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0); //socket的描述浮
+ if(sockfd == -1)
+ {
+ perror("socket");
+ exit(1);
+ }
+
+ bzero(&info, sizeof(info)); //初始化,將struct涵蓋的bits設為0
+ info.sin_family = AF_INET; //使用IPv4協定的地址
+ //info.sin_addr.s_addr = inet_addr(ip); //IP address, inet_addr()可將字串IP變成 binary's IP
+ info.sin_addr.s_addr = inet_addr("127.0.0.1");//先指向自己的 IP 練習, 可以把防火牆打開測試connected的timeout
+ info.sin_port = htons(502); //埠號,Host TO Network Short integer的縮寫,它將本機端的字節序(endian)轉換成了網路端的字節序
+
+ //socket的連線
+ //沒有timeout版本的connect
+ if((connect(sockfd, (struct sockaddr *)&info, sizeof(info))) == -1)
+ {
+ perror("connect");
+ exit(1);
+ }
+
+ //傳送資料(send a message on a socket),如正確 send 會回傳實際送出的 Byte 數
+ if((send(sockfd, buf, sizeof(buf), 0)) == -1)
+ {
+ perror("send");
+ exit(1);
+ }
+ printf("After the send function \n\n");
+
+ //接收資料,如正確 recv 會回傳實際讀到並寫入到 buffer 的 Byte 數
+ numbytes = recv(sockfd, buf, sizeof(buf), 0);
+ if(numbytes == -1)
+ {
+ perror("recv");
+ exit(1);
+ }
+
+ close(sockfd);
+
+ buf[numbytes] = '\0';
+
+ return 0;
+
+}
+///////////////////// main ///////////////////////////////////////////
+
+int main(int argc, char *argv[])
+{
+ int return_code;
+ int version;
+ int date;
+
+ return_code = atoi(argv[4]);
+ version = atoi(argv[6]);
+ date = atoi(argv[8]);
+ sprintf(serial, "%s", argv[9]);
+
+ readConfig(); //呼叫存取ip,password等等變數的function
+ if(return_code == 0) //如return_code為0,則輸出0且結束
+ printf("0\n"); //do nothing
+ else if(return_code == 400)
+ puts("工作失敗\n");
+ else if(return_code == 666)
+ puts("上一個程式還在執行中\n");
+ else if(return_code == 777)
+ puts("已完成\n");
+ else if(return_code == 10|| return_code == 110 || return_code == 20 || return_code == 120 ||
+ return_code == 1 || return_code == 101 || return_code == 200 || return_code == 300)
+ {
+ tcpConnect(666, ""); //呼叫tcp function會回處理中(參數666)
+ errorCountPlus: //如errorCountR or errorCountT <3會用goto回到這裡再執行一次
+ switch(return_code)
+ {
+ case 10: //如return_code為 010 則上傳 vAlert8.cfg
+ sprintf(command, "./ftpUpload.exe %s %s %s %s %s vAlert8.cfg STOR", ip, port, user, password, folder);
+ //printf("test command %s\n", command); //sprintf 為,把這些格式的值寫到command中
+ system(command); //叫 system 去執行command(自己設的變數)
+ FileTransferOk();
+ break;
+ case 110: //如return_code為 110 則下載 vAlert8.cfg
+ sprintf(command, "./ftpClient.exe %s %s %s %s vAlert8.cfg reset\n", ip, port, user, password);
+ //printf("%s\n", command);
+ system(command);
+ FileRevOk();
+ break;
+ case 20: //如return_code為 020 則上傳 vAlert8Common.cfg
+ sprintf(command, "./ftpUpload.exe %s %s %s %s %s vAlert8Common.cfg STOR", ip, port, user, password, folder);
+ //printf("%s\n", command);
+ system(command);
+ FileTransferOk();
+ break;
+ case 120: //如return_code為 120 則下載 vAlert8Common.cfg
+ sprintf(command, "./ftpClient.exe %s %s %s %s vAlert8Common.cfg reset", ip, port, user, password);
+ //printf("%s\n",command);
+ system(command);
+ FileRevOk();
+ break;
+ case 1: //如return_code為 001 則上傳清單上的檔案,需先下載再上傳檔案清單
+ sprintf(command, "./ftpClient.exe %s %s %s %s uploadFileList_%s reset", ip, port, user, password, serial);
+ system(command); //先下載檔案
+ FileRevOk();
+
+ FILE *fp3;
+ fp3 = fopen("uploadFileList.txt","r");
+ if(fp3 == NULL)
+ {
+ printf("open failure\n");
+ }
+ else //再上傳檔案清單
+ {
+ char temp[500];
+ fgets(temp, 500, fp3);
+ sprintf(command,"./ftpUpload.exe %s %s %s %s %s/%s uploadFileList_%s STOR", ip, port, user, password, folder, temp, serial);
+ //printf("%s\n", command);
+ system(command);
+ FileTransferOk();
+ }
+ fclose(fp3);
+ break;
+ case 101: //如return_code為 101 則單純下載檔案清單
+ sprintf(command, "./ftpClients.exe %s %s %s %s uploadFileList_%s reset", ip, port, user, password, serial);
+ //printf("%s\n", command);
+ system(command);
+ FileRevOk();
+ break;
+ case 200:
+ puts("更新韌體\n");
+ updateFirmware();
+ break;
+ case 300: //如return_code為 300 則先下載 run_serial.sh,並執行排程
+ sprintf(command, "./ftpClient.exe %s %s %s %s run_%s.sh reset", ip, port, user, password, serial);
+ //printf("%s\n", command);
+ system(command);
+ FileRevOk();
+
+ sprintf(command, "sudo chmod +x run_%s.sh", serial);//改成可執行檔
+ //printf("first %s\n", command);
+ system(command);
+
+ sprintf(command, "sudo ./run_%s.sh", serial); //執行排程
+ //printf("second %s\n", command);
+ system(command);
+ break;
+ }//end switch
+ }//end else if
+ else
+ {
+ puts("wrong code\n");
+ }
+ if(checkR == 0 && checkT == 0) //FileRevOk && FileTransferOk 的結果都收到OK回傳777
+ {
+ tcpConnect(777, "");
+ }
+ else //Received 沒收到三次會回傳400
+ {
+ if(checkR != 0 && errorCountR < 3)
+ {
+ errorCountR++;
+ printf("Received fail %d time\n", errorCountR);
+ checkR = 0;
+ goto errorCountPlus;
+ }
+ else if(checkR == -1)
+ tcpConnect(400, "popen()_error");
+ else if(checkR == -2)
+ tcpConnect(400, "file_not_recv");
+
+
+ if(checkT != 0 && errorCountT < 3) //Transfer 沒收到三次會回傳400
+ {
+ errorCountT++;
+ printf("Transfer fail %d time\n", errorCountT);
+ checkT = 0;
+ goto errorCountPlus;
+ }
+ else if(checkT == -1)
+ tcpConnect(400, "popen()_error");
+ else if(checkT == -2)
+ tcpConnect(400, "file_not_transfer");
+ }
+
+ return 0;
+}
\ No newline at end of file