Пример #1
0
void sem_debug_add(const xSemaphoreHandle handle, const char *name,
		   bool is_semaphore)
{
	int temp, i;
	if (sem_mutex) {
		temp = os_mutex_get(&sem_mutex, OS_WAIT_FOREVER);
		if (temp == -WM_FAIL) {
			wmprintf("[sem-dbg] Failed to get sem-mutex\r\n");
			return;
		}
	}
	for (i = 0;  i < MAX_SEM_INFO_BUF; i++) {
		if (semdbg[i].x_queue == 0) {
			if (name && strlen(name)) {
				semdbg[i].q_name =
					os_mem_alloc(strlen(name)+1);
				if (semdbg[i].q_name == NULL)
					break;
				strcpy(semdbg[i].q_name, name);
			}
			semdbg[i].x_queue = handle;
			semdbg[i].is_semaphore = is_semaphore;
			semcnt++;
			break;
		}
	}
	if (sem_mutex)
		os_mutex_put(&sem_mutex);
	return;
}
Пример #2
0
/***********************************************************
*  Function: get_gw_status
*  Input: 
*  Output: 
*  Return: GW_STAT_E
***********************************************************/
GW_STAT_E get_gw_status(VOID)
{
    GW_STAT_E stat;
    os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
    stat = gw_cntl.stat;
    os_mutex_put(&gw_mutex);

    return stat;
}
Пример #3
0
/***********************************************************
*  Function: get_wf_gw_status
*  Input: 
*  Output: 
*  Return: GW_WIFI_STAT_E
***********************************************************/
GW_WIFI_STAT_E get_wf_gw_status(VOID)
{
    GW_WIFI_STAT_E wf_stat;

    os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
    wf_stat = gw_cntl.wf_stat;
    os_mutex_put(&gw_mutex);

    return wf_stat;
}
Пример #4
0
static void os_dump_seminfo()
{
	int i = 0, temp;
	const unsigned int *px_queue = NULL;
	unsigned int *list;
	char *pc_write_buffer = os_mem_alloc(MAX_WAITER_BUF);
	if (pc_write_buffer == NULL)
		return;

	if (sem_mutex) {
		temp = os_mutex_get(&sem_mutex, OS_WAIT_FOREVER);
		if (temp == -WM_FAIL) {
			wmprintf("[sem-dbg] Failed to get sem-mutex\r\n");
			os_mem_free(pc_write_buffer);
			return;
		}
	}

	if (semcnt > 0) {
		wmprintf("%-32s%-8s%-50s%s", "Name", "Count", "Waiters",
			 "Type\r\n");
	}

	for (i = 0; i < MAX_SEM_INFO_BUF; i++) {
		if (semdbg[i].x_queue == 0)
			continue;
		if (semdbg[i].q_name && isascii(semdbg[i].q_name[0])) {
			wmprintf("%-32s", semdbg[i].q_name);
		} else {
			wmprintf("%-32s", "-");
		}
		px_queue = semdbg[i].x_queue;
		wmprintf("%-8d",
			 os_semaphore_getcount(&semdbg[i].x_queue));
		vGetWaiterListFromHandle(px_queue, &list);
		vGetTaskNamesInList((signed char *) pc_write_buffer,
				    MAX_WAITER_BUF - 1,
				    (const unsigned int *)list);
		pc_write_buffer[MAX_WAITER_BUF - 1] = '\0';
		wmprintf("%-50s ", pc_write_buffer);
		(semdbg[i].is_semaphore == 0) ?
			wmprintf("q") :
			wmprintf("s");
		wmprintf("\r\n");
	}
	if (sem_mutex)
		os_mutex_put(&sem_mutex);
	os_mem_free(pc_write_buffer);
}
Пример #5
0
/* Main CLI processing thread
 *
 * Waits to receive a command buffer pointer from an input collector, and
 * then processes.  Note that it must cleanup the buffer when done with it.
 *
 * Input collectors handle their own lexical analysis and must pass complete
 * command lines to CLI.
 */
static void cli_main(os_thread_arg_t data)
{
	os_mutex_get(&cli_mutex, OS_WAIT_FOREVER);
	while (1) {
		int ret;
		char *msg;

		msg = NULL;
		ret = os_queue_recv(&cli.input_queue, &msg, RX_WAIT);
		if (ret != WM_SUCCESS) {
			if (ret == WM_E_BADF) {
				wmprintf("Error: CLI fatal queue error."
					       "\r\n");
/* Special case fatal errors.  Shouldn't happen. If it does
 * it means CLI is fatally corrupted, so end the thread.
 */
				return;
			}
/* A number of other non-fatal conditions can cause us to get here]
 * without a message to process, if so, just go back and wait.
 */
			continue;
		}

/* HALT message indicates that this thread will be deleted
 * shortly. Hence this function need to do necessary actions
 * required before getting deleted.
 * HALT message is not dynamically allocated,
 * hence msg doesn't need to be freed up in that case.
 */
		if (msg != NULL) {
			if (strcmp(msg, HALT_MSG) == 0)
				break;
			ret = handle_input(msg);
			if (ret == 1)
				print_bad_command(msg);
			else if (ret == 2)
				wmprintf("syntax error\r\n");
			wmprintf(PROMPT);
			/* done with it, clean up the message (we own it) */
			cli_mem_free(&msg);
		}
	}
	os_mutex_put(&cli_mutex);
	os_thread_self_complete(NULL);
}
Пример #6
0
int lcd_drv_write(mdev_t *dev, const char *line1, const char *line2)
{
	int ret;
	ret = wakelock_get(WL_ID_LCD_WRITE);
	if (ret != WM_SUCCESS)
		return ret;

	ret = os_mutex_get(&lcd_mutex, OS_WAIT_FOREVER);
	if (ret == -WM_FAIL) {
		lcd_e("failed to get mutex");
		wakelock_put(WL_ID_LCD_WRITE);
		return ret;
	}
	__write_to_lcd(dev, line1, line2);
	os_mutex_put(&lcd_mutex);

	wakelock_put(WL_ID_LCD_WRITE);

	return 0;
}
Пример #7
0
static void gw_actv_timer_cb(os_timer_arg_t arg)
{
    GW_WIFI_STAT_E wf_stat;
    wf_stat = get_wf_gw_status();
    if(wf_stat != STAT_STA_CONN) {
        // PR_DEBUG("we can not active gw,because the wifi state is :%d",wf_stat);
        return;
    }
    else {
        PR_DEBUG("now,we'll go to active gateway");
    }

    OPERATE_RET op_ret;
    #if NO_DEF_GW_DEV_ACTV_IF
    op_ret = httpc_gw_active();
    if(OPRT_OK != op_ret) {
        PR_ERR("op_ret:%d",op_ret);
        return;
    }
    #else
    op_ret = httpc_gw_dev_active(&(gw_cntl.dev->dev_if));
    if(OPRT_OK != op_ret) {
        PR_ERR("httpc_gw_dev_active error:%d",op_ret);
        return;
    }

    os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
    gw_cntl.dev->dev_if.bind = TRUE;
    gw_cntl.dev->dev_if.sync = FALSE;
    os_mutex_put(&gw_mutex);
    
    op_ret = ws_db_set_dev_if(&gw_cntl.dev->dev_if);
    if(OPRT_OK != op_ret) {
        PR_ERR("ws_db_set_dev_if error,op_ret:%d",op_ret);
    }
    #endif
    check_all_dev_if_update();

    os_timer_deactivate(&gw_actv_timer);
}
Пример #8
0
VOID update_dev_ol_status(IN CONST CHAR *id,IN CONST BOOL online)
{
    if(id == NULL) {
        return;
    }

    DEV_CNTL_N_S *dev_cntl = get_dev_cntl(id);
    if(NULL == dev_cntl) {
        PR_ERR("do not get dev cntl");
        return;
    }

    if((get_gw_status() <= UN_ACTIVE) || \
        FALSE == dev_cntl->dev_if.bind) {
        return;
    }

    os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
    dev_cntl->online = online;
    os_mutex_put(&gw_mutex);

    check_dev_need_update(dev_cntl);
}
Пример #9
0
void sem_debug_delete(const xSemaphoreHandle handle)
{
	int temp, i;
	if (sem_mutex) {
		temp = os_mutex_get(&sem_mutex, OS_WAIT_FOREVER);
		if (temp == -WM_FAIL) {
			wmprintf("[sem-dbg] Failed to get sem-mutex\r\n");
			return;
		}
	}
	for (i = 0; i < MAX_SEM_INFO_BUF; i++) {
		if (semdbg[i].x_queue == handle) {
			semdbg[i].x_queue  = 0;
			os_mem_free(semdbg[i].q_name);
			semdbg[i].q_name = NULL;
			semcnt--;
			break;
		}
	}
	if (sem_mutex)
		os_mutex_put(&sem_mutex);
	return;
}
bool CO2_dataRecieve(void)
{
    uint8_t data[9];
    int i, len, sz;

    /* transmit command data */
    os_mutex_get(&co2uart_mutex, OS_WAIT_FOREVER);
    uart_drv_write(uart2_dev, cmd_get_sensor, 9); //sizeof(cmd_get_sensor));
    os_mutex_put(&co2uart_mutex);

    os_thread_sleep(10); /* delay of 10 milisecs */

    /* begin reveiceing data */
    for(i = 0; i < 9; i++) {
        len = 0;
        while(len++ < 100) { /* Ready each byte until it is received, timeout 100msec*/
            sz = uart_drv_read(uart2_dev, &data[i], 1);
            if (sz == 1) {
                /* If a bute is read then store and move to next */
                break;
            } else
                os_thread_sleep(1); /* delay of 1 milisecs */
        }
    }

    if((i != 9) || (1 + (0xFF ^ (uint8_t)(data[1] + data[2] + data[3]
                                          + data[4] + data[5] + data[6] + data[7]))) != data[8]) {
        wmprintf("Received Data Checksum Error\r\n");
        return false;
    }

    CO2PPM = (int)data[2] * 256 + (int)data[3];
    temperature = (int)data[4] - 40;

    wmprintf("Tempr: %d, CORPPM: %d\r\n", temperature, CO2PPM);
    return true;
}
Пример #11
0
/***********************************************************
*  Function: check_and_update_dev_desc_if
*  Input: 
*  Output: 
*  Return: 
***********************************************************/
VOID check_and_update_dev_desc_if(IN CONST CHAR *id,\
                                  IN CONST CHAR *name,\
                                  IN CONST CHAR *sw_ver,\
                                  IN CONST CHAR *schema_id,\
                                  IN CONST CHAR *ui_id)
{
    if(id == NULL) {
        return;
    }

    DEV_CNTL_N_S *dev_cntl = get_dev_cntl(id);
    if(NULL == dev_cntl) {
        PR_ERR("do not get dev cntl");
        return;
    }

    CONST CHAR *str[] = {name,sw_ver,schema_id,ui_id};
    CHAR *oldstr[] = {dev_cntl->dev_if.name,dev_cntl->dev_if.sw_ver,\
                      dev_cntl->dev_if.schema_id,dev_cntl->dev_if.ui_id};
    INT i;

    os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
    for(i = 0;i < CNTSOF(str);i++) {
        if(NULL == str[i]) {
            continue;
        }
        
        if(strcmp(str[i],oldstr[i]) || \
           (strlen(str[i]) != strlen(oldstr[i]))) {
            dev_cntl->dev_if.sync = TRUE;
            strcpy(oldstr[i],str[i]);
        }
    }
    os_mutex_put(&gw_mutex);

    check_dev_need_update(dev_cntl);
}
/**
 * @brief Try to lock the provided mutex
 *
 * Call this function to attempt to lock the mutex before performing a state change
 * Non-Blocking, immediately returns with failure if lock attempt fails
 *
 * @param IoT_Mutex_t - pointer to the mutex to be locked
 * @return IoT_Error_t - error code indicating result of operation
 */
IoT_Error_t aws_iot_thread_mutex_trylock(IoT_Mutex_t *pMutex) {
	if (os_mutex_get(&pMutex->lock, OS_NO_WAIT) != WM_SUCCESS) {
		return MUTEX_LOCK_ERROR;
	}
	return AWS_SUCCESS;
}
Пример #13
0
/***********************************************************
*  Function: set_gw_status
*  Input: 
*  Output: 
*  Return: 
***********************************************************/
VOID set_gw_status(IN CONST GW_STAT_E stat)
{
    os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
    gw_cntl.stat = stat;
    os_mutex_put(&gw_mutex);
}
Пример #14
0
mdev_t *ssp_drv_open(SSP_ID_Type ssp_id, SSP_FrameFormat_Type format,
		SSP_MS_Type mode, SSP_DMA dma, int cs, bool level)
{
	int ret;
	SSP_CFG_Type sspCfgStruct;
	SSP_FIFO_Type sspFifoCfg;
	SPI_Param_Type spiParaStruct;
	SSP_NWK_Type sspNetworkCfg;
	PSP_Param_Type pspParaStruct;
	sspdev_data_t *ssp_data_p;
	mdev_t *mdev_p = mdev_get_handle(mdev_ssp_name[ssp_id]);
	ssp_data_p = (sspdev_data_t *) mdev_p->private_data;

	if (mdev_p == NULL) {
		SSP_LOG("Unable to open device %s\r\n",
			mdev_ssp_name[ssp_id]);
		return NULL;
	}
	ssp_data_p->slave = mode;
	ret = os_mutex_get(&ssp_mutex[mdev_p->port_id], OS_WAIT_FOREVER);
	if (ret == -WM_FAIL) {
		SSP_LOG("failed to get mutex\r\n");
		return NULL;
	}
	/* If ringbuffer size is not set by user then set to default size */
	if (GET_RX_BUF_SIZE(ssp_data_p) == 0) {
		SET_RX_BUF_SIZE(ssp_data_p, SSP_RX_BUF_SIZE);
	}
	if (rx_buf_init(ssp_data_p)) {
		SSP_LOG("Unable to allocate ssp software ring buffer\r\n");
		return NULL;
	}
	/* If clk is not set by user then set it to default */
	if (ssp_data_p->freq == 0) {
		ret = ssp_drv_set_clk(mdev_p->port_id, DEFAULT_SSP_FREQ);
	}

	/* Configure the pinmux for ssp pins */
	if (cs >= 0 && mode == SSP_MASTER) {
		board_ssp_pin_config(mdev_p->port_id, 0);
		/* Use user specified chip select pin */
		ssp_data_p->cs = cs;
		ssp_data_p->cs_level = level;
		GPIO_PinMuxFun(cs, PINMUX_FUNCTION_0);
		GPIO_SetPinDir(cs, GPIO_OUTPUT);
		/* Initially keep slave de-selected */
		GPIO_WritePinOutput(cs, !level);
	} else {
		board_ssp_pin_config(mdev_p->port_id, 1);
	}

	/* Configure SSP interface */
	sspCfgStruct.mode = SSP_NORMAL;
	sspCfgStruct.masterOrSlave = mode;
	sspCfgStruct.trMode = SSP_TR_MODE;
	sspCfgStruct.dataSize = SSP_DATASIZE_8;
	sspCfgStruct.sfrmPola = SSP_SAMEFRM_PSP;
	sspCfgStruct.slaveClkRunning = SSP_SLAVECLK_TRANSFER;
	sspCfgStruct.txd3StateEnable = ENABLE;
	/* RXFIFO inactivity timeout, [timeout = 100 / 26MHz] (Bus clock) */
	sspCfgStruct.timeOutVal = 100;

	switch (format) {
	case SSP_FRAME_SPI:
		sspCfgStruct.frameFormat = SSP_FRAME_SPI;
		sspCfgStruct.txd3StateType = SSP_TXD3STATE_ELSB;
		break;
	case SSP_FRAME_PSP:
		sspCfgStruct.frameFormat = SSP_FRAME_PSP;
		sspCfgStruct.txd3StateType = SSP_TXD3STATE_12SLSB;
		break;
	case SSP_FRAME_SSP:
		SSP_LOG("Frame Format not implemented.\r\n");
		return NULL;
	}

	/* Configure SSP Fifo */
	sspFifoCfg.fifoPackMode =  DISABLE;

	/* See if dma needs to be enabled */
	if (dma == DMA_ENABLE) {
		/* Enable DMA controller clock */
		CLK_ModuleClkEnable(CLK_DMAC);
		sspFifoCfg.rxFifoFullLevel = SSP_DMA_FIFO_RX_THRESHOLD;
		sspFifoCfg.txFifoEmptyLevel = SSP_DMA_FIFO_TX_THRESHOLD;
		sspFifoCfg.rxDmaService = ENABLE;
		sspFifoCfg.txDmaService = ENABLE;
		ssp_data_p->dma = 1;
		sspCfgStruct.trailByte = SSP_TRAILBYTE_DMA;
	} else {
		sspFifoCfg.rxFifoFullLevel = SSP_FIFO_RX_THRESHOLD;
		sspFifoCfg.txFifoEmptyLevel = SSP_FIFO_TX_THRESHOLD;
		sspFifoCfg.rxDmaService = DISABLE;
		sspFifoCfg.txDmaService = DISABLE;
		sspCfgStruct.trailByte = SSP_TRAILBYTE_CORE;
	}

	/* Let the settings take effect */
	SSP_Disable(mdev_p->port_id);
	SSP_Init(mdev_p->port_id, &sspCfgStruct);
	SSP_FifoConfig(mdev_p->port_id, &sspFifoCfg);

	/* Do frame format config */
	switch (format) {
	case SSP_FRAME_SPI:
		spiParaStruct.spiClkPhase = SPI_SCPHA_1;
		spiParaStruct.spiClkPolarity = SPI_SCPOL_LOW;
		SPI_Config(mdev_p->port_id, &spiParaStruct);
		break;
	case SSP_FRAME_PSP:
		pspParaStruct.pspFsrtType = 0;
		pspParaStruct.pspClkMode = PSP_DRIVFALL_SAMPRISE_IDLELOW;
		pspParaStruct.pspFrmPola = PSP_SFRMP_LOW;
		pspParaStruct.pspEndTransState = PSP_ENDTRANS_LOW;
		pspParaStruct.startDelay = 0;
		pspParaStruct.dummyStart = 0;
		pspParaStruct.dummyStop = 0;
		pspParaStruct.frmDelay = 0;
		pspParaStruct.frmLength = 8;
		PSP_Config(mdev_p->port_id, &pspParaStruct);
		sspNetworkCfg.frameRateDiv = 1;
		sspNetworkCfg.txTimeSlotActive = 3;
		sspNetworkCfg.rxTimeSlotActive = 3;
		SSP_NwkConfig(mdev_p->port_id, &sspNetworkCfg);
		break;
	case SSP_FRAME_SSP:
		SSP_LOG("Frame Format not implemented.\r\n");
		return NULL;
	}

	/* Enable read interrupts only for slave when dma is disabled*/
	if (mode == SSP_SLAVE && dma == DMA_DISABLE) {
		install_int_callback(SSP_INT_BASE + mdev_p->port_id,
				     SSP_INT_RFFI,
				     ssp_read_irq_handler[mdev_p->port_id]);
		NVIC_EnableIRQ(SSP_IRQn_BASE + mdev_p->port_id);
		NVIC_SetPriority(SSP_IRQn_BASE + mdev_p->port_id, 0xF);
		SSP_IntMask(mdev_p->port_id, SSP_INT_RFFI, UNMASK);
	}

	SSP_Enable(mdev_p->port_id);
	return mdev_p;
}
Пример #15
0
static void dev_ul_timer_cb(os_timer_arg_t arg)
{
    if(get_gw_status() <= ACTIVE_RD) {
        os_timer_deactivate(&dev_ul_timer);
    }

    GW_WIFI_STAT_E wf_stat;
    wf_stat = get_wf_gw_status();
    if(wf_stat != STAT_STA_CONN) {
        // PR_DEBUG("we can not update info,because the wifi state is :%d",wf_stat);
        return;
    }
    else {
        PR_DEBUG("now,we'll go to update device info");
    }

    // TODO 1 http device bind 
    //      2 device info update
    GW_CNTL_S *gw_cntl = get_gw_cntl();
    DEV_CNTL_N_S *dev_cntl = NULL;
    BOOL close_timer = TRUE;
    OPERATE_RET op_ret = OPRT_OK;

    for(dev_cntl = gw_cntl->dev;dev_cntl;dev_cntl = dev_cntl->next) {        
        // device bind
        if(FALSE == dev_cntl->dev_if.bind) {
            PR_DEBUG("bind");
            op_ret = httpc_dev_bind(&dev_cntl->dev_if);
            if(OPRT_OK != op_ret) {
                close_timer = FALSE;
                continue;
            }

            os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
            dev_cntl->dev_if.bind = TRUE;
            dev_cntl->dev_if.sync = FALSE;
            os_mutex_put(&gw_mutex);

            op_ret = ws_db_set_dev_if(&dev_cntl->dev_if);
            if(OPRT_OK != op_ret) {
                PR_ERR("ws_db_set_dev_if error,op_ret:%d",op_ret);
            }
        }

        // device info update
        if(TRUE == dev_cntl->dev_if.sync && \
           TRUE == dev_cntl->dev_if.bind) {
            PR_DEBUG("update");
            op_ret = httpc_dev_update(&dev_cntl->dev_if);
            if(OPRT_OK != op_ret) {
                close_timer = FALSE;
                continue;
            }

            os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
            dev_cntl->dev_if.sync = FALSE;
            os_mutex_put(&gw_mutex);

            op_ret = ws_db_set_dev_if(&dev_cntl->dev_if);
            if(OPRT_OK != op_ret) {
                PR_ERR("ws_db_set_dev_if error,op_ret:%d",op_ret);
            }
        }
    }

    if(TRUE == close_timer) {
        int ret = os_timer_deactivate(&dev_ul_timer);;
        PR_DEBUG("close timer ret:%d",ret);
    }
}
Пример #16
0
/***********************************************************
*  Function: set_wf_gw_status
*  Input: 
*  Output: 
*  Return: 
***********************************************************/
VOID set_wf_gw_status(IN CONST GW_WIFI_STAT_E wf_stat)
{
    os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
    gw_cntl.wf_stat = wf_stat;
    os_mutex_put(&gw_mutex);
}
Пример #17
0
/***********************************************************
*  Function: gw_lc_bind_device
*  Input: 
*  Output: 
*  Return: 
***********************************************************/
OPERATE_RET gw_lc_bind_device(IN CONST DEV_DESC_IF_S *dev_if,\
                              IN CONST CHAR *sch_json_arr)
{
    if(NULL == dev_if || \
       NULL == sch_json_arr) {
        return OPRT_INVALID_PARM;
    }

    if(get_dev_cntl(dev_if->id)) {
        return OPRT_OK;
    }

    cJSON *root = NULL;
    OPERATE_RET op_ret = OPRT_OK;
    root = cJSON_Parse(sch_json_arr);
    if(NULL == root) {
        return OPRT_CJSON_PARSE_ERR;
    }
    
    INT dp_num;
    DEV_CNTL_N_S *dev_cntl = NULL;
    dp_num = cJSON_GetArraySize(root);
    if(0 == dp_num) {
        op_ret = OPRT_INVALID_PARM;
        goto ERR_EXIT;
    }

    dev_cntl = (DEV_CNTL_N_S *)Malloc(sizeof(DEV_CNTL_N_S)+dp_num*sizeof(DP_CNTL_S));
    if(NULL == dev_cntl) {
        op_ret = OPRT_MALLOC_FAILED;
        goto ERR_EXIT;
    }
    memset(dev_cntl,0,sizeof(DEV_CNTL_N_S)+dp_num*sizeof(DP_CNTL_S));

    memcpy(&dev_cntl->dev_if,dev_if,sizeof(DEV_DESC_IF_S));
    dev_cntl->dp_num = dp_num;

    // dp schema parse
    INT i;
    DP_DESC_IF_S *dp_desc;
    DP_PROP_VALUE_U *prop;
    cJSON *cjson;
    cJSON *next;
    
    for(i = 0;i < dev_cntl->dp_num;i++) {        
        dp_desc = &(dev_cntl->dp[i].dp_desc);
        prop = &(dev_cntl->dp[i].prop);

        cjson = cJSON_GetArrayItem(root,i);
        if(NULL == cjson) {
            op_ret = OPRT_CJSON_GET_ERR;
            goto ERR_EXIT;
        }

        // id
        next = cJSON_GetObjectItem(cjson,"id");
        if(NULL == next) {
            PR_ERR("get id null");
            op_ret = OPRT_CJSON_GET_ERR;
            goto ERR_EXIT;
        }
        if(next->type == cJSON_String) {
            dp_desc->dp_id = atoi(next->valuestring);
        }else {
            dp_desc->dp_id = next->valueint;
        }

        // mode
        next = cJSON_GetObjectItem(cjson,"mode");
        if(NULL == next) {
            PR_ERR("get mode null");
            op_ret = OPRT_CJSON_GET_ERR;
            goto ERR_EXIT;
        }
        if(!strcmp(next->valuestring,"rw")) {
            dp_desc->mode = M_RW;
        }else if(!strcmp(next->valuestring,"ro")) {
            dp_desc->mode = M_RO;
        }else {
            dp_desc->mode = M_WR;
        }

        // passive
        next = cJSON_GetObjectItem(cjson,"passive");
        if(next == NULL) {
            dp_desc->passive = FALSE;
        }else {
            dp_desc->passive = next->type;
            dev_cntl->preprocess = TRUE;
        }
        
        // trigger
        next = cJSON_GetObjectItem(cjson,"trigger");
        if(NULL == next) {
            dp_desc->trig_t = TRIG_PULSE;
        }else {
            if(!strcmp(next->valuestring,"pulse")) {
                dp_desc->trig_t = TRIG_PULSE;
            }else {
                dp_desc->trig_t = TRIG_DIRECT;
            }
        }

        // type
        next = cJSON_GetObjectItem(cjson,"type");
        if(NULL == next) {
            PR_ERR("get type null");
            op_ret = OPRT_CJSON_GET_ERR;
            goto ERR_EXIT;
        }
        if(!strcmp(next->valuestring,"obj")) {
            dp_desc->type = T_OBJ;
        }else if(!strcmp(next->valuestring,"raw")) {
            dp_desc->type = T_RAW;
            continue;
        }else {
            dp_desc->type = T_FILE;
            continue;
        }

        // property
        next = cJSON_GetObjectItem(cjson,"property");
        if(NULL == next) {
            PR_ERR("get property null");
            op_ret = OPRT_CJSON_GET_ERR;
            goto ERR_EXIT;
        }
        cJSON *child;
        child = cJSON_GetObjectItem(next,"type");
        if(NULL == next) {
            PR_ERR("get type null");
            op_ret = OPRT_CJSON_GET_ERR;
            goto ERR_EXIT;
        }
        if(!strcmp(child->valuestring,"bool")) {
            dp_desc->prop_tp = PROP_BOOL;
        }else if(!strcmp(child->valuestring,"value")) {
            dp_desc->prop_tp = PROP_VALUE;

            CHAR *str[] = {"max","min","scale"};
            INT i;
            for(i = 0; i < CNTSOF(str);i++) {
                child = cJSON_GetObjectItem(next,str[i]);
                if(NULL == child && (i != CNTSOF(str)-1)) {
                    PR_ERR("get property null");
                    op_ret = OPRT_CJSON_GET_ERR;
                    goto ERR_EXIT;
                }else if(NULL == child && (i == CNTSOF(str)-1)) {
                    prop->prop_value.scale = 0;
                }else {
                    switch(i) {
                        case 0: prop->prop_value.max = child->valueint; break;
                        case 1: prop->prop_value.min = child->valueint; break;
                        //case 2: prop->prop_value.step = child->valueint; break;
                        case 2: prop->prop_value.scale = child->valueint; break;
                    }
                }
            }
        }else if(!strcmp(child->valuestring,"string")) {
            dp_desc->prop_tp = PROP_STR;
            child = cJSON_GetObjectItem(next,"maxlen");
            if(NULL == child) {
                PR_ERR("get maxlen null");
                op_ret = OPRT_CJSON_GET_ERR;
                goto ERR_EXIT;
            }
            prop->prop_str.max_len = child->valueint;
            prop->prop_str.value = Malloc(prop->prop_str.max_len+1);
            if(NULL == prop->prop_str.value) {
                PR_ERR("malloc error");
                op_ret = OPRT_MALLOC_FAILED;
                goto ERR_EXIT;
            }
        }else {
            dp_desc->prop_tp = PROP_ENUM;
            child = cJSON_GetObjectItem(next,"range");
            if(NULL == child) {
                PR_ERR("get range null");
                op_ret = OPRT_CJSON_GET_ERR;
                goto ERR_EXIT;
            }
            
            INT i,num;
            num = cJSON_GetArraySize(child);
            if(num == 0) {
                PR_ERR("get array size error");
                op_ret = OPRT_CJSON_GET_ERR;
                goto ERR_EXIT;
            }
            prop->prop_enum.pp_enum = Malloc(num*sizeof(CHAR *));
            if(NULL == prop->prop_enum.pp_enum) {
                PR_ERR("malloc error");
                op_ret = OPRT_MALLOC_FAILED;
                goto ERR_EXIT;
            }

            prop->prop_enum.cnt = num;
            for(i = 0;i < num;i++) {
                cJSON *c_child = cJSON_GetArrayItem(child,i);
                if(NULL == c_child) {
                    PR_ERR("get array null");
                    op_ret = OPRT_CJSON_GET_ERR;
                    goto ERR_EXIT;
                }

                prop->prop_enum.pp_enum[i] = cJSON_strdup(c_child->valuestring);
                if(NULL == prop->prop_enum.pp_enum[i]) {
                    PR_ERR("malloc error");
                    op_ret = OPRT_MALLOC_FAILED;
                    goto ERR_EXIT;
                }
            }
        }
    }

    os_mutex_get(&gw_mutex, OS_WAIT_FOREVER);
    if(NULL == gw_cntl.dev) {
        gw_cntl.dev = dev_cntl;
    }else {
        DEV_CNTL_N_S *tmp_dev_cntl = gw_cntl.dev;
        while(tmp_dev_cntl->next) {
            tmp_dev_cntl = tmp_dev_cntl->next;
        }
        tmp_dev_cntl->next = dev_cntl;
    }
    gw_cntl.dev_num++;
    os_mutex_put(&gw_mutex);

    if(root) {
        cJSON_Delete(root);
    }

    return OPRT_OK;

ERR_EXIT:
    if(dev_cntl) {
        Free(dev_cntl);
    }

    if(root) {
        cJSON_Delete(root);
    }

    return op_ret;
}