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);
 |