forked from xuos/xiuos
				
			
		
			
				
	
	
		
			355 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			355 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
| /*
 | |
| * Copyright (c) 2022 AIIT XUOS Lab
 | |
| * XiUOS is licensed under Mulan PSL v2.
 | |
| * You can use this software according to the terms and conditions of the Mulan PSL v2.
 | |
| * You may obtain a copy of Mulan PSL v2 at:
 | |
| *        http://license.coscl.org.cn/MulanPSL2
 | |
| * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | |
| * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | |
| * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | |
| * See the Mulan PSL v2 for more details.
 | |
| */
 | |
| 
 | |
| /**
 | |
|  * @file control.c
 | |
|  * @brief code for control framework app
 | |
|  * @version 3.0
 | |
|  * @author AIIT XUOS Lab
 | |
|  * @date 2022-09-27
 | |
|  */
 | |
| 
 | |
| #include <control.h>
 | |
| #include <control_def.h>
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Find certain Protocol
 | |
|  * @param void
 | |
|  * @return Control Protocol pointer
 | |
|  */
 | |
| ControlProtocolType ControlProtocolFind(void)
 | |
| {
 | |
|     return control_protocol;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Protocol Init
 | |
|  * @param control_protocol - control protocol pointer
 | |
|  * @return success : 0 error : -1
 | |
|  */
 | |
| static int ControlProtocolInit(ControlProtocolType control_protocol)
 | |
| {
 | |
|     CONTROL_PARAM_CHECK(control_protocol);
 | |
|     int ret = -1;
 | |
| 
 | |
|     control_protocol->protocol_status = CONTROL_INIT;
 | |
| 
 | |
|     ret = PrivMutexCreate(&control_protocol->lock, 0);
 | |
|     if(ret < 0) {
 | |
|         printf("ControlProtocolInit mutex create failed.\n");
 | |
|         goto _out;
 | |
|     }
 | |
| 
 | |
|     ret = PrivSemaphoreCreate(&control_protocol->sem, 0, 0);
 | |
|     if (ret < 0) {
 | |
|         printf("ControlProtocolInit create sem error\n");
 | |
|         goto _out;
 | |
|     }
 | |
| 
 | |
| _out:
 | |
|     return ret;    
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @description: Analyze Recipe
 | |
|  * @param control_protocol - Control Protocol pointer
 | |
|  * @param recipe_name - recipe name
 | |
|  * @return success : 0 error : -1
 | |
|  */
 | |
| static int ControlAnalyzeRecipe(ControlProtocolType control_protocol, const char *recipe_name)
 | |
| {
 | |
|     int recipe_file_fd = -1;
 | |
|     struct stat recipe_file_status;
 | |
|     uint16_t recipe_file_length = 0;
 | |
|     char *recipe_file_buf;
 | |
| 
 | |
|     /*wait for SD-card mount done*/
 | |
|     PrivTaskDelay(5000);
 | |
| 
 | |
|     //Step1 : read recipe file data from SD card or other store device
 | |
|     recipe_file_fd = PrivOpen(recipe_name, O_RDONLY);
 | |
|     if (recipe_file_fd < 0) {
 | |
|         printf("Open recipe file %s failed\n", recipe_name);
 | |
|         PrivClose(recipe_file_fd);
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     if (0 != fstat(recipe_file_fd, &recipe_file_status)) {
 | |
|         printf("Get recipe file information failed!\n");
 | |
|         PrivClose(recipe_file_fd);
 | |
|         return -1;
 | |
|     } else {
 | |
|         recipe_file_length = recipe_file_status.st_size;
 | |
|     }
 | |
| 
 | |
|     recipe_file_buf = PrivMalloc(recipe_file_length);
 | |
|     if (NULL == recipe_file_buf) {
 | |
|         printf("Get recipe file memory failed!\n");
 | |
|         PrivFree(recipe_file_buf);
 | |
|         PrivClose(recipe_file_fd);
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     if (PrivRead(recipe_file_fd, recipe_file_buf, recipe_file_length) < 0) {
 | |
|         printf("Read recipe file failed!\n");
 | |
|         PrivFree(recipe_file_buf);
 | |
|         PrivClose(recipe_file_fd);
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     PrivClose(recipe_file_fd);  
 | |
| 
 | |
|     //Step2 : CJSON analyze
 | |
| #ifdef LIB_USING_CJSON
 | |
|     cJSON *recipe_file_json = cJSON_Parse(recipe_file_buf);
 | |
|     if (NULL == recipe_file_json) {
 | |
|         printf("Parse recipe_file_buf failed!\n");
 | |
|         return -1;
 | |
|     }
 | |
|     
 | |
|     control_protocol->recipe = (struct ControlRecipe *)PrivMalloc(sizeof(struct ControlRecipe));
 | |
|     memset(control_protocol->recipe, 0, sizeof(struct ControlRecipe));
 | |
| 
 | |
|     /*Get basic information from recipe file*/
 | |
|     if (RecipeBasicInformation(control_protocol->recipe, recipe_file_json) < 0) {
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     strncpy(control_protocol->device->dev_name, control_protocol->recipe->device_name, 20);
 | |
|     control_protocol->protocol_type = control_protocol->recipe->protocol_type;
 | |
| 
 | |
|     /*Get the variable need to read from recipe file*/
 | |
|     RecipeReadVariableItem(control_protocol->recipe, recipe_file_json);
 | |
| 
 | |
|     control_protocol->done = control_protocol->recipe->done;
 | |
| 
 | |
|     cJSON_Delete(recipe_file_json);
 | |
| 
 | |
|     PrivFree(recipe_file_buf);
 | |
|     printf("Read and parse recipe file done!\n");
 | |
| #endif
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Protocol Open
 | |
|  * @param control_protocol - Control Protocol pointer
 | |
|  * @return success : 0 error : -1
 | |
|  */
 | |
| int ControlProtocolOpen(struct ControlProtocol *control_protocol)
 | |
| {
 | |
|     CONTROL_PARAM_CHECK(control_protocol);
 | |
|     CONTROL_PARAM_CHECK(control_protocol->done);
 | |
|     int ret = -1;
 | |
| 
 | |
|     if (control_protocol->done->_open) {
 | |
|         ret = control_protocol->done->_open(control_protocol);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Protocol Close
 | |
|  * @param control_protocol - Control Protocol pointer
 | |
|  * @return success : 0 error : -1
 | |
|  */
 | |
| int ControlProtocolClose(struct ControlProtocol *control_protocol)
 | |
| {
 | |
|     CONTROL_PARAM_CHECK(control_protocol);
 | |
|     CONTROL_PARAM_CHECK(control_protocol->done);
 | |
|     int ret = -1;
 | |
| 
 | |
|     if (control_protocol->done->_close) {
 | |
|         ret = control_protocol->done->_close(control_protocol);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Protocol Read Data
 | |
|  * @param control_protocol - Control Protocol pointer
 | |
|  * @param buf - read buffer
 | |
|  * @param len - read data length
 | |
|  * @return success : data length error : -1
 | |
|  */
 | |
| int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
 | |
| {
 | |
|     CONTROL_PARAM_CHECK(control_protocol);
 | |
|     CONTROL_PARAM_CHECK(control_protocol->done);
 | |
|     int ret = -1;
 | |
| 
 | |
|     if (control_protocol->done->_read) {
 | |
|         ret = control_protocol->done->_read(control_protocol, buf, len);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Protocol Write Cmd
 | |
|  * @param control_protocol - Control Protocol pointer
 | |
|  * @param buf - write buffer
 | |
|  * @param len - write data length
 | |
|  * @return success : data length error : -1
 | |
|  */
 | |
| int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len)
 | |
| {
 | |
|     CONTROL_PARAM_CHECK(control_protocol);
 | |
|     CONTROL_PARAM_CHECK(control_protocol->done);
 | |
|     int ret = -1;
 | |
| 
 | |
|     if (control_protocol->done->_write) {
 | |
|         ret = control_protocol->done->_write(control_protocol, buf, len);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Protocol Ioctl
 | |
|  * @param control_protocol - Control Protocol pointer
 | |
|  * @param cmd - ioctl cmd
 | |
|  * @param args - args
 | |
|  * @return success : 0 error : -1
 | |
|  */
 | |
| int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args)
 | |
| {
 | |
|     CONTROL_PARAM_CHECK(control_protocol);
 | |
|     CONTROL_PARAM_CHECK(control_protocol->done);
 | |
|     int ret = -1;
 | |
| 
 | |
|     if (control_protocol->done->_ioctl) {
 | |
|         ret = control_protocol->done->_ioctl(control_protocol, cmd, args);
 | |
|     }
 | |
| 
 | |
|     return ret;    
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Init
 | |
|  * @param void
 | |
|  * @return success : 0 error : -1
 | |
|  */
 | |
| int ControlFrameworkInit(void)
 | |
| {
 | |
|     int ret = 0;
 | |
| 
 | |
|     control_protocol = (struct ControlProtocol *)PrivMalloc(sizeof(struct ControlProtocol));
 | |
|     if (NULL == control_protocol) {
 | |
|         printf("%s malloc control protocol failed!\n", __func__);
 | |
|         PrivFree(control_protocol);
 | |
|         ret = -1;
 | |
|         goto _out;
 | |
|     }
 | |
| 
 | |
|     control_protocol->device = (struct ControlDevice *)PrivMalloc(sizeof(struct ControlDevice));
 | |
|     if (NULL == control_protocol->device) {
 | |
|         printf("%s malloc control device failed!\n", __func__);
 | |
|         PrivFree(control_protocol->device);
 | |
|         PrivFree(control_protocol);
 | |
|         ret = -1;
 | |
|         goto _out;
 | |
|     }
 | |
|     
 | |
|     //Control Protocol Struct Init
 | |
|     ret = ControlProtocolInit(control_protocol);
 | |
|     if (ret < 0) {
 | |
|         printf("%s failed!\n", __func__);
 | |
|         PrivFree(control_protocol);
 | |
|         goto _out;
 | |
|     }
 | |
| 
 | |
|     printf("%s malloc CONTROL_RECIPE_FILE %s\n", __func__, CONTROL_RECIPE_FILE);
 | |
| 
 | |
|     //Read Recipe File, Get Control Protocol Configure Param
 | |
|     ret = ControlAnalyzeRecipe(control_protocol, CONTROL_RECIPE_FILE);
 | |
|     if (ret < 0) {
 | |
|         printf("%s failed!\n", __func__);
 | |
|         PrivFree(control_protocol);
 | |
|         goto _out;
 | |
|     }
 | |
| 
 | |
|     control_protocol->protocol_status = CONTROL_REGISTERED;
 | |
|     control_protocol->device->status = CONTROL_REGISTERED;
 | |
| 
 | |
|     ret = ControlPeripheralInit(control_protocol->recipe);
 | |
|     if (ret < 0) {
 | |
|         printf("%s failed!\n", __func__);
 | |
|         PrivFree(control_protocol);
 | |
|         goto _out;
 | |
|     }
 | |
|     
 | |
|     printf("%u %u\n",control_protocol->recipe->total_data_length,control_protocol->recipe->device_id);
 | |
| 
 | |
|     printf("%s ControlPeripheralInit done\n", __func__);
 | |
| 
 | |
| _out:
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static char *const protocol_type_str[] =
 | |
| {
 | |
|     "TYPE_START",
 | |
|     "S7",
 | |
|     "MODBUS_TCP",
 | |
|     "MODBUS_UART",
 | |
|     "OPC_UA",
 | |
|     "FINS",
 | |
|     "MELSEC_1E",
 | |
|     "MELSEC_3E_Q_L",
 | |
|     "MELSEC_3E_IQ_R",
 | |
|     "MELSEC_1C",
 | |
|     "MELSEC_3C",
 | |
|     "TYPE_END"
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * @description: Control Framework Shell Cmd Information
 | |
|  * @param void
 | |
|  * @return success : 0 error : -1
 | |
|  */
 | |
| void ShowControl(void)
 | |
| {
 | |
|     int i = 0; 
 | |
|     int maxlen;
 | |
|     const char *item_type = "control_protocol_type";
 | |
|     const char *item_name_0 = "control_protocol_name";
 | |
|     const char *item_name_1 = "control_device_name";
 | |
|     const char *item_status = "status";
 | |
| 
 | |
|     ControlProtocolType control_protocol = ControlProtocolFind();
 | |
| 
 | |
|     printf(" %-28s%-28s%-26s%-20s\n", item_type, item_name_0, item_name_1, item_status); 
 | |
|     maxlen = 90;
 | |
|     while (i < maxlen) {
 | |
|         i++;
 | |
|         if (maxlen == i) {
 | |
|             printf("-\n");
 | |
|         } else {
 | |
|             printf("-");
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (control_protocol) {
 | |
|         printf("%s", " ");
 | |
|         KPrintf("%-28s%-28s%-26s%-8d\n", 
 | |
|             protocol_type_str[1], 
 | |
|             protocol_type_str[1],
 | |
|             control_protocol->device->dev_name,
 | |
|             control_protocol->device->status);
 | |
|     }
 | |
| }
 | |
| PRIV_SHELL_CMD_FUNCTION(ShowControl, show control framework information, PRIV_SHELL_CMD_FUNC_ATTR);
 |