Exemplo n.º 1
0
static rt_int32_t mp3_decoder_fill_buffer(struct mp3_decoder* decoder)
{
	rt_size_t bytes_read;
	rt_size_t bytes_to_read;

	// rt_kprintf("left: %d. refilling inbuffer...\n", decoder->bytes_left);
	if (decoder->bytes_left > 0)
	{
		// better: move unused rest of buffer to the start
		rt_memmove(decoder->read_buffer, decoder->read_ptr, decoder->bytes_left);
	}

	bytes_to_read = (MP3_AUDIO_BUF_SZ - decoder->bytes_left) & ~(512 - 1);

	bytes_read = decoder->fetch_data(decoder->fetch_parameter,
		(rt_uint8_t *)(decoder->read_buffer + decoder->bytes_left),
        bytes_to_read);

	if (bytes_read != 0)
	{
		decoder->read_ptr = decoder->read_buffer;
		decoder->read_offset = 0;
		decoder->bytes_left = decoder->bytes_left + bytes_read;
		return 0;
	}
	else
	{
		rt_kprintf("can't read more data\n");
		return -1;
	}
}
Exemplo n.º 2
0
/** 
 *  @brief This function handles the command response of get_hw_spec
 *  
 *  @param priv    A pointer to wlan_private structure
 *  @param resp	   A pointer to HostCmd_DS_COMMAND
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
static int wlan_ret_get_hw_spec(WlanCard *cardinfo, HostCmd_DS_COMMAND * resp)
{
	u32 i;
	HostCmd_DS_GET_HW_SPEC *hwspec = &resp->params.hwspec;
	WlanCard *card = cardinfo;
	int ret = WLAN_STATUS_SUCCESS;

	card->fwCapInfo = hwspec->fwCapInfo;

	card->RegionCode = hwspec->RegionCode;
	WlanDebug(WlanMsg,"RegionCode %x,set 0x10",card->RegionCode);
	card->RegionCode = 0x10;
	for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++)
	{
		/* use the region code to search for the index */
		if (card->RegionCode == RegionCodeToIndex[i])
		{
			break;
		}
	}

	/* if it's unidentified region code, use the default (USA) */
	if (i >= MRVDRV_MAX_REGION_CODE)
	{
		card->RegionCode = 0x10;
		WlanDebug(WlanMsg,"unidentified region code, use the default (USA)\n");
	}

	if (card->MyMacAddress[0] == 0xff)
	{
		rt_memmove(card->MyMacAddress, hwspec->PermanentAddr, ETH_ALEN);
		hexdump("default Mac address:", card->MyMacAddress, ETH_ALEN);
	}

	/* firmware release number */
	WlanDebug(WlanMsg, "FW release number: 0x%08x\n", hwspec->FWReleaseNumber);
	WlanDebug(WlanMsg, "HW version: 0x%08x\n", hwspec->Version);

	if (wlan_set_regiontable(card, card->RegionCode, 0))
	{
		ret = WLAN_STATUS_FAILURE;
		goto done;
	}

	if (wlan_set_universaltable(card, 0))
	{
		ret = WLAN_STATUS_FAILURE;
		goto done;
	}

done: 
    return ret;
}
Exemplo n.º 3
0
static void mem_DebugFree(void *p, const char *fn, const int line)
{
	t_mem_debug *pDebug;

	if (p == NULL)
		return;
	mem_Lock();
	for (pDebug = &mem_debug[0]; pDebug < &mem_debug[mem_nCnt]; pDebug++)
		if (pDebug->p == p) {
			rt_memmove(pDebug, pDebug + 1, (uint_t)&mem_debug[mem_nCnt] - (uint_t)pDebug);
			break;
		}
	if (pDebug == &mem_debug[mem_nCnt]) {
		list_memdebug(0, ARR_SIZE(mem_debug));
		rt_kprintf("memory error:%X no malloc to free\n", (uint_t)p);
	}
	mem_nCnt -= 1;
	RT_ASSERT(mem_nCnt >= 0);
	mem_Unlock();
}
Exemplo n.º 4
0
rt_err_t log_trace_register_session(struct log_trace_session *session)
{
    unsigned int lvl, i;

    if (_the_sess_nr == LOG_TRACE_MAX_SESSION)
        return -RT_EFULL;

    if (session == RT_NULL)
        return RT_EOK;

    lvl = rt_hw_interrupt_disable();
    /* inserting the sessions in ascending order.
     *
     * this might take relatively long time. But since the register should only
     * happen when initialize the whole system, this should not be a matter. */
    for (i = 0; i < _the_sess_nr; i++)
    {
        if (_the_sessions[i]->id.num > session->id.num)
        {
            rt_memmove(_the_sessions+i, _the_sessions+i+1, _the_sess_nr-i);
            _the_sessions[i] = session;
            break;
        }
        else if (_the_sessions[i]->id.num == session->id.num)
        {
            rt_kprintf("registering session 0x%p twice\n", session);
            rt_hw_interrupt_enable(lvl);
            return -RT_ERROR;
        }
    }
    if (i == _the_sess_nr)
        _the_sessions[i] = session;
    _the_sess_nr++;
    rt_hw_interrupt_enable(lvl);

    return RT_EOK;
}
Exemplo n.º 5
0
/** 
 *  @brief This function prepares command of set_wep.
 *  
 *  @param card		A pointer to WlanCard structure
 *  @param cmd_oid   OID: ADD_WEP KEY or REMOVE_WEP KEY
 *  @return 	   	WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
int wlan_cmd_802_11_set_wep(WlanCard *cardinfo, u32 cmd_oid)
{
	WlanCard *card = cardinfo;
	HostCmd_DS_802_11_SET_WEP *wep = NULL;
	HostCmd_DS_COMMAND *CmdPtr = NULL;
	int ret = WLAN_STATUS_SUCCESS;

	CmdPtr = rt_malloc(sizeof(HostCmd_DS_COMMAND));
	if (CmdPtr == NULL)
	{
		WlanDebug(WlanErr,"memory allocate failed for set wep\r\n");
		return WLAN_STATUS_FAILURE;
	}
	cardinfo->SeqNum++;
	CmdPtr->SeqNum = cardinfo->SeqNum;
	CmdPtr->Result = 0;
	wep = &CmdPtr->params.wep;

	if (cmd_oid == OID_802_11_ADD_WEP)
	{
		CmdPtr->Command = HostCmd_CMD_802_11_SET_WEP;
		CmdPtr->Size = (sizeof(HostCmd_DS_802_11_SET_WEP) + S_DS_GEN);
		wep->Action = HostCmd_ACT_ADD;
		wep->KeyIndex = (card->CurrentWepKeyIndex & HostCmd_WEP_KEY_INDEX_MASK);

		switch (card->WepKey[0].KeyLength)
		{
		case WEP_40_BIT_LEN:
			wep->WEPTypeForKey1 = HostCmd_TYPE_WEP_40_BIT;
			rt_memmove(wep->WEP1, card->WepKey[0].KeyMaterial,
					card->WepKey[0].KeyLength);
			break;
		case WEP_104_BIT_LEN:
			wep->WEPTypeForKey1 = HostCmd_TYPE_WEP_104_BIT;
			rt_memmove(wep->WEP1, card->WepKey[0].KeyMaterial,
					card->WepKey[0].KeyLength);
			break;
		case 0:
			break;
		default:
			WlanDebug(WlanErr,"Set Wep key0 length %d\r\n",card->WepKey[0].KeyLength);
			ret = WLAN_STATUS_FAILURE;
			goto done;
		}

		switch (card->WepKey[1].KeyLength)
		{
		case WEP_40_BIT_LEN:
			wep->WEPTypeForKey2 = HostCmd_TYPE_WEP_40_BIT;
			rt_memmove(wep->WEP2, card->WepKey[1].KeyMaterial,
					card->WepKey[1].KeyLength);
			break;
		case WEP_104_BIT_LEN:
			wep->WEPTypeForKey2 = HostCmd_TYPE_WEP_104_BIT;
			rt_memmove(wep->WEP2, card->WepKey[1].KeyMaterial,
					card->WepKey[1].KeyLength);
			break;
		case 0:
			break;
		default:
			WlanDebug(WlanErr,"Set Wep Key1 Length = %d \n",card->WepKey[1].KeyLength);
			ret = WLAN_STATUS_FAILURE;
			goto done;
		}

		switch (card->WepKey[2].KeyLength)
		{
		case WEP_40_BIT_LEN:
			wep->WEPTypeForKey3 = HostCmd_TYPE_WEP_40_BIT;
			rt_memmove(wep->WEP3, card->WepKey[2].KeyMaterial,
					card->WepKey[2].KeyLength);
			break;
		case WEP_104_BIT_LEN:
			wep->WEPTypeForKey3 = HostCmd_TYPE_WEP_104_BIT;
			rt_memmove(wep->WEP3, card->WepKey[2].KeyMaterial,
					card->WepKey[2].KeyLength);
			break;
		case 0:
			break;
		default:
			WlanDebug(WlanErr,"Set Wep Key2 Length = %d \n",card->WepKey[1].KeyLength);
			ret = WLAN_STATUS_FAILURE;
			goto done;
		}

		switch (card->WepKey[3].KeyLength)
		{
		case WEP_40_BIT_LEN:
			wep->WEPTypeForKey4 = HostCmd_TYPE_WEP_40_BIT;
			rt_memmove(wep->WEP4, card->WepKey[3].KeyMaterial,
					card->WepKey[3].KeyLength);
			break;
		case WEP_104_BIT_LEN:
			wep->WEPTypeForKey4 = HostCmd_TYPE_WEP_104_BIT;
			rt_memmove(wep->WEP4, card->WepKey[3].KeyMaterial,
					card->WepKey[3].KeyLength);
			break;
		case 0:
			break;
		default:
			WlanDebug(WlanErr,"Set Wep Key3 Length = %d \n",card->WepKey[1].KeyLength);
			ret = WLAN_STATUS_FAILURE;
			goto done;
		}
	}
	else if (cmd_oid == OID_802_11_REMOVE_WEP)
	{
		CmdPtr->Command = (HostCmd_CMD_802_11_SET_WEP);
		CmdPtr->Size = (sizeof(HostCmd_DS_802_11_SET_WEP)) + S_DS_GEN;
		wep->Action = HostCmd_ACT_REMOVE;

		/* default tx key index */
		wep->KeyIndex = ((u16) (card->CurrentWepKeyIndex
				& (u32) HostCmd_WEP_KEY_INDEX_MASK));
	}
	ret = WlanExecuteCommand(cardinfo, CmdPtr);

	if (ret)
	{
		WlanDebug(WlanErr,"cmd Set Wep Key failed \n");
		ret = WLAN_STATUS_FAILURE;
	}
	rt_free(CmdPtr);
	ret = WLAN_STATUS_SUCCESS;
	done: return ret;
}
Exemplo n.º 6
0
/** 
 *  @brief This function prepares command of snmp_mib.
 *  
 *  @param priv		A pointer to wlan_private structure
 *  @param cmd	   	A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   the action: GET or SET
 *  @param cmd_oid   	the OID of SNMP MIB
 *  @param pdata_buf	the pointer to data buffer
 *  @return 	   	WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
int wlan_cmd_802_11_snmp_mib(WlanCard *cardinfo, int cmd_action, int cmd_oid,
		void *pdata_buf)
{
	WlanCard *card = cardinfo;
	HostCmd_DS_802_11_SNMP_MIB *pSNMPMIB = NULL;
	HostCmd_DS_COMMAND *CmdPtr = NULL;
	u8 ucTemp;
	int ret = WLAN_STATUS_SUCCESS;

	CmdPtr = rt_malloc(sizeof(HostCmd_DS_COMMAND));
	if (CmdPtr == NULL)
	{
		WlanDebug(WlanErr,"memory allocate failed for set SNMP\r\n");
		return WLAN_STATUS_FAILURE;

	}

	card->SeqNum++;
	CmdPtr->SeqNum = card->SeqNum;
	CmdPtr->Command = HostCmd_CMD_802_11_SNMP_MIB;
	CmdPtr->Result = 0;

	pSNMPMIB = &CmdPtr->params.smib;
	CmdPtr->Size = (sizeof(HostCmd_DS_802_11_SNMP_MIB) + S_DS_GEN);

	switch (cmd_oid)
	{
	case OID_802_11_INFRASTRUCTURE_MODE:
		pSNMPMIB->QueryType = (HostCmd_ACT_GEN_SET);
		pSNMPMIB->OID = ((u16) DesiredBssType_i);
		pSNMPMIB->BufSize = (sizeof(u8));
		if (card->InfrastructureMode == Wlan802_11Infrastructure)
			ucTemp = SNMP_MIB_VALUE_INFRA;
		else
			ucTemp = SNMP_MIB_VALUE_ADHOC;

		rt_memmove(pSNMPMIB->Value, &ucTemp, sizeof(u8));

		break;

	case OID_802_11D_ENABLE:
	{
		u32 ulTemp;

		pSNMPMIB->OID = (u16) Dot11D_i;

		if (cmd_action == HostCmd_ACT_SET)
		{
			pSNMPMIB->QueryType = HostCmd_ACT_GEN_SET;
			pSNMPMIB->BufSize = sizeof(u16);
			ulTemp = *(u32 *) pdata_buf;
			*((u16*) (pSNMPMIB->Value)) = ((u16) ulTemp);
		}
		break;
	}

	case OID_802_11_FRAGMENTATION_THRESHOLD:
	{
		WLAN_802_11_FRAGMENTATION_THRESHOLD ulTemp;

		pSNMPMIB->OID = ((u16) FragThresh_i);

		if (cmd_action == HostCmd_ACT_GET)
		{
			pSNMPMIB->QueryType = (HostCmd_ACT_GEN_GET);
		}
		else if (cmd_action == HostCmd_ACT_SET)
		{
			pSNMPMIB->QueryType = (HostCmd_ACT_GEN_SET);
			pSNMPMIB->BufSize = (sizeof(u16));
			ulTemp = *((WLAN_802_11_FRAGMENTATION_THRESHOLD *) pdata_buf);
			*((u16*) (pSNMPMIB->Value)) = ((u16) ulTemp);

		}

		break;
	}

	case OID_802_11_RTS_THRESHOLD:
	{

		WLAN_802_11_RTS_THRESHOLD ulTemp;
		pSNMPMIB->OID = ((u16) RtsThresh_i);

		if (cmd_action == HostCmd_ACT_GET)
		{
			pSNMPMIB->QueryType = HostCmd_ACT_GEN_GET;
		}
		else if (cmd_action == HostCmd_ACT_SET)
		{
			pSNMPMIB->QueryType = (HostCmd_ACT_GEN_SET);
			pSNMPMIB->BufSize = (sizeof(u16));
			ulTemp = *((WLAN_802_11_RTS_THRESHOLD *) pdata_buf);
			*(u16*) (pSNMPMIB->Value) = ((u16) ulTemp);

		}
		break;
	}
	case OID_802_11_TX_RETRYCOUNT:
		pSNMPMIB->OID = ((u16) ShortRetryLim_i);

		if (cmd_action == HostCmd_ACT_GET)
		{
			pSNMPMIB->QueryType = (HostCmd_ACT_GEN_GET);
		}
		else if (cmd_action == HostCmd_ACT_SET)
		{
			pSNMPMIB->QueryType = (HostCmd_ACT_GEN_SET);
			pSNMPMIB->BufSize = (sizeof(u16));
			*((u16*) (pSNMPMIB->Value)) = ((u16) card->TxRetryCount);
		}

		break;
	default:
		break;
	}

	WlanDebug(WlanCmd,"SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x, Value=0x%x\r\n",
			pSNMPMIB->QueryType, pSNMPMIB->OID, pSNMPMIB->BufSize,
			*(u16 *) pSNMPMIB->Value);

	ret = WlanExecuteCommand(card, CmdPtr);
	if (ret)
	{
		WlanDebug(WlanErr,"Failure for set SNMP\r\n");
		ret = WLAN_STATUS_FAILURE;
	}
	rt_free(CmdPtr);
	return WLAN_STATUS_SUCCESS;
}
Exemplo n.º 7
0
static rt_bool_t rtgui_textbox_onkey(struct rtgui_object *widget, rtgui_event_t *event)
{
	rtgui_textbox_t *box = RTGUI_TEXTBOX(widget);
	struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd *)event;
	rt_size_t length;
	rt_uint16_t posbak = box->position;

	RT_ASSERT(box != RT_NULL);
	RT_ASSERT(ekbd != RT_NULL);

	/* handle the key at down time and nothing to do with up */
	if (RTGUI_KBD_IS_UP(ekbd))
		return RT_TRUE;

	if (box->dis_length == 0)
	{
		rtgui_rect_t rect;

		rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);

		if (box->font_width == 0)
			return RT_FALSE;

		box->dis_length = ((rtgui_rect_width(rect) - 5) / box->font_width) & ~0x1;
	}

	length = rt_strlen((char*)box->text);
	if (ekbd->key == RTGUIK_DELETE)
	{
        int chw;
        unsigned char *c;

        if (TB_ABSPOS(box) == length)
        {
            goto _exit;
        }
        chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box)).char_width;

        /* remove character */
        for (c = &box->text[TB_ABSPOS(box)]; c[chw] != '\0'; c++)
            *c = c[chw];
        *c = '\0';
	}
	else if (ekbd->key == RTGUIK_BACKSPACE)
	{
		/* delete front character */
		if (box->position == 0)
		{
			if(box->first_pos == 0)
                goto _exit;

            if(box->first_pos > box->dis_length)
            {
                int head_fix;
                int chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box) - 1).char_width;

                rt_memmove(box->text + TB_ABSPOS(box) - chw,
                           box->text + TB_ABSPOS(box),
                           length - TB_ABSPOS(box) + 1);

                head_fix = 0;
                /* FIXME: */
                if (box->text[box->first_pos - box->dis_length - chw] > 0x80)
                {
                    int i;

                    for (i = box->first_pos - box->dis_length - chw;
                         i < box->first_pos;
                         i++)
                    {
                        if (box->text[i] > 0x80)
                            head_fix++;
                        else
                            break;
                    }
                    /* if the head is in middle of wide char, move one less
                     * byte */
                    head_fix = head_fix % 2;
                }

                box->first_pos = box->first_pos - box->dis_length
                                 + head_fix - chw;
                box->position  = box->dis_length - head_fix;
            }
            else
            {
                int chw;
                if (box->text[TB_ABSPOS(box) - 1] < 0x80)
                {
                    /* also copy the \0 */
                    rt_memmove(box->text + TB_ABSPOS(box) - 1,
                               box->text + TB_ABSPOS(box),
                                  length - TB_ABSPOS(box) + 1);
                    chw = 1;
                }
                else
                {
                    rt_memmove(box->text + TB_ABSPOS(box) - 2,
                               box->text + TB_ABSPOS(box),
                                  length - TB_ABSPOS(box) + 1);
                    chw = 2;
                }
                box->position = box->first_pos - chw;
                box->first_pos = 0;
            }
		}
		else
		{
            unsigned char *c;
            int chw;

            chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box) - 1).char_width;

            /* remove character */
            for (c = &box->text[TB_ABSPOS(box) - chw]; c[chw] != '\0'; c++)
                *c = c[chw];
            *c = '\0';

            box->position -= chw;
		}
	}
	else if (ekbd->key == RTGUIK_LEFT)
	{
        int chw;

        if (box->first_pos == 0 && box->position == 0)
            goto _exit;

        if (box->text[TB_ABSPOS(box) - 1] > 0x80)
            chw = 2;
        else
            chw = 1;

		/* move to prev */
		if (box->position >= chw)
		{
            box->position -= chw;
		}
		else
		{
            if (box->first_pos >= chw)
                box->first_pos -= chw;
            else
                box->first_pos = 0;
		}
	}
	else if (ekbd->key == RTGUIK_RIGHT)
	{
        int chw;

        if ((TB_ABSPOS(box) + 2) <= length &&
            box->text[TB_ABSPOS(box)] > 0x80)
            chw = 2;
        else
            chw = 1;

		/* move to next */
		if (TB_ABSPOS(box) < length)
		{
			if(box->position + chw <= box->dis_length)
				box->position += chw;
			else
            {
                /* always move one wide char when the first char is wide */
                if (box->text[box->first_pos] > 0x80)
                {
                    box->first_pos += 2;
                    if (chw == 2)
                    {
                        int i;
                        int head_fix = 0;
                        for (i = box->first_pos;
                             i < box->first_pos + box->dis_length;
                             i++)
                        {
                            if (box->text[i] > 0x80)
                                head_fix++;
                        }
                        head_fix %= 2;
                        if (head_fix)
                        {
                            box->first_pos += 2;
                            box->position = box->dis_length - 1;
                        }
                    }
                    else if (chw == 1)
                        /* we have moved the box by 2 bytes but the last one is
                         * a narrow char */
                        box->position -= 1;
                    else
                        RT_ASSERT(0);
                }
                else
                    box->first_pos += chw;
            }
		}
	}
	else if (ekbd->key == RTGUIK_HOME)
	{
		/* move cursor to start */
		box->position = 0;
		box->first_pos = 0;
	}
	else if (ekbd->key == RTGUIK_END)
	{
		/* move cursor to end */
		if(length > box->dis_length)
		{
			box->position = box->dis_length;
			box->first_pos = length - box->dis_length;
		}
		else
		{
			box->position = length;
			box->first_pos = 0;
		}
	}
	else if (ekbd->key == RTGUIK_RETURN)
	{
		if (box->on_enter != RT_NULL)
		{
			box->on_enter(box, event);
		}
	}
	else if (ekbd->key == RTGUIK_NUMLOCK)
	{
		/* change numlock state */
		/*
		extern void update_number_lock(void);
		update_number_lock();
		*/
	}
	else
    {
        rt_uint16_t chr;
        int chw;

        if (!(ekbd->unicode || isprint(ekbd->key)))
            goto _exit;

        if (ekbd->unicode)
        {
            chr = ekbd->unicode;
            chw = 2;
        }
        else
        {
            chr = ekbd->key;
            chw = 1;
        }

        if (box->flag & RTGUI_TEXTBOX_DIGIT)
        {
            /* only input digit */
            if (!isdigit(chr))
            {
                /* exception: '.' and '-' */
                if (chr != '.' && chr != '-')return RT_FALSE;
                if (chr == '.' && strchr((char*)box->text, '.'))return RT_FALSE;

                if (chr == '-')
                {
                    if (length + chw > box->line_length) return RT_FALSE;

                    if (strchr((char*)box->text, '-'))
                    {
                        unsigned char *c;
                        for (c = &box->text[0]; c != &box->text[length]; c++)
                            *c = *(c + 1);
                        box->text[length] = '\0';
                        box->position --;
                        goto _exit;
                    }
                    else
                    {
                        unsigned char *c;
                        for (c = &box->text[length]; c != &box->text[0]; c--)
                            *c = *(c - 1);
                        box->text[0] = '-';
                        box->text[length + 1] = '\0';
                        box->position ++;
                        goto _exit;
                    }
                }
            }
        }

        if (length + chw > box->line_length)
            return RT_FALSE;

        if (TB_ABSPOS(box) <= length - 1)
        {
            unsigned char *c;

            for (c = &box->text[length + chw - 1];
                 c != &box->text[TB_ABSPOS(box)];
                 c -= 1)
                *c = *(c - chw);
        }

        if (chw == 1)
        {
            box->text[TB_ABSPOS(box)] = chr;
        }
        else if (chw == 2)
        {
            box->text[TB_ABSPOS(box)] = chr >> 8;
            box->text[TB_ABSPOS(box)+1] = chr & 0xFF;
        }
        else
        {
Exemplo n.º 8
0
void finsh_thread_entry(void* parameter)
{
    char ch;

	/* normal is echo mode */
	shell->echo_mode = 1;

    finsh_init(&shell->parser);
	rt_kprintf(FINSH_PROMPT);

	/* set console device as shell device */
	shell->device = rt_console_get_device();
	if (shell->device != RT_NULL)
	{
		rt_device_open(shell->device, RT_DEVICE_OFLAG_RDWR);
		rt_device_set_rx_indicate(shell->device, finsh_rx_ind);
	}

	while (1)
	{
		/* wait receive */
		if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;

		/* read one character from device */
		while (rt_device_read(shell->device, 0, &ch, 1) == 1)
		{
			/*
			 * handle control key
			 * up key  : 0x1b 0x5b 0x41
			 * down key: 0x1b 0x5b 0x42
			 * right key:0x1b 0x5b 0x43
			 * left key: 0x1b 0x5b 0x44
			 */
			if (ch == 0x1b)
			{
				shell->stat = WAIT_SPEC_KEY;
				continue;
			}
			else if (shell->stat == WAIT_SPEC_KEY)
			{
				if (ch == 0x5b)
				{
					shell->stat = WAIT_FUNC_KEY;
					continue;
				}

				shell->stat = WAIT_NORMAL;
			}
			else if (shell->stat == WAIT_FUNC_KEY)
			{
				shell->stat = WAIT_NORMAL;

				if (ch == 0x41) /* up key */
				{
#ifdef FINSH_USING_HISTORY
					/* prev history */
					if (shell->current_history > 0)
						shell->current_history --;
					else
					{
						shell->current_history = 0;
						continue;
					}

					/* copy the history command */
					memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
						   FINSH_CMD_SIZE);
					shell->line_curpos = shell->line_position = strlen(shell->line);
					finsh_handle_history(shell);
#endif
					continue;
				}
				else if (ch == 0x42) /* down key */
				{
#ifdef FINSH_USING_HISTORY
					/* next history */
					if (shell->current_history < shell->history_count - 1)
						shell->current_history ++;
					else
					{
						/* set to the end of history */
						if (shell->history_count != 0)
							shell->current_history = shell->history_count - 1;
						else
							continue;
					}

					memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
						   FINSH_CMD_SIZE);
					shell->line_curpos = shell->line_position = strlen(shell->line);
					finsh_handle_history(shell);
#endif
					continue;
				}
				else if (ch == 0x44) /* left key */
				{
					if (shell->line_curpos)
					{
						rt_kprintf("\b");
						shell->line_curpos --;
					}

					continue;
				}
				else if (ch == 0x43) /* right key */
				{
					if (shell->line_curpos < shell->line_position)
					{
						rt_kprintf("%c", shell->line[shell->line_curpos]);
						shell->line_curpos ++;
					}

					continue;
				}

			}

			/* handle CR key */
			if (ch == '\r')
			{
				char next;

				if (rt_device_read(shell->device, 0, &next, 1) == 1)
					ch = next;
				else ch = '\r';
			}
			/* handle tab key */
			else if (ch == '\t')
			{
				int i;
				/* move the cursor to the beginning of line */
				for (i = 0; i < shell->line_curpos; i++)
					rt_kprintf("\b");

				/* auto complete */
				finsh_auto_complete(&shell->line[0]);
				/* re-calculate position */
				shell->line_curpos = shell->line_position = strlen(shell->line);

				continue;
			}
			/* handle backspace key */
			else if (ch == 0x7f || ch == 0x08)
			{
				/* note that shell->line_curpos >= 0 */
				if (shell->line_curpos == 0)
					continue;

				shell->line_position--;
				shell->line_curpos--;

				if (shell->line_position > shell->line_curpos)
				{
					int i;

					rt_memmove(&shell->line[shell->line_curpos],
							   &shell->line[shell->line_curpos + 1],
							   shell->line_position - shell->line_curpos);
					shell->line[shell->line_position] = 0;

					rt_kprintf("\b%s  \b", &shell->line[shell->line_curpos]);

					/* move the cursor to the origin position */
					for (i = shell->line_curpos; i <= shell->line_position; i++)
						rt_kprintf("\b");
				}
				else
				{
					rt_kprintf("\b \b");
					shell->line[shell->line_position] = 0;
				}

				continue;
			}

			/* handle end of line, break */
			if (ch == '\r' || ch == '\n')
			{
#ifdef FINSH_USING_MSH
				if (msh_is_used() == RT_TRUE && shell->line_position != 0)
				{
					rt_kprintf("\n");
					msh_exec(shell->line, shell->line_position);
					#ifdef FINSH_USING_HISTORY
					finsh_push_history(shell);
					#endif
				}
				else
#endif
				{
					/* add ';' and run the command line */
					shell->line[shell->line_position] = ';';

					#ifdef FINSH_USING_HISTORY
					finsh_push_history(shell);
					#endif

					if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
					else rt_kprintf("\n");
				}

				rt_kprintf(FINSH_PROMPT);
				memset(shell->line, 0, sizeof(shell->line));
				shell->line_curpos = shell->line_position = 0;

				break;
			}

			/* it's a large line, discard it */
			if (shell->line_position >= FINSH_CMD_SIZE)
				shell->line_position = 0;

			/* normal character */
			if (shell->line_curpos < shell->line_position)
			{
				int i;

				rt_memmove(&shell->line[shell->line_curpos + 1],
						   &shell->line[shell->line_curpos],
						   shell->line_position - shell->line_curpos);
				shell->line[shell->line_curpos] = ch;
				if (shell->echo_mode)
					rt_kprintf("%s", &shell->line[shell->line_curpos]);

				/* move the cursor to new position */
				for (i = shell->line_curpos; i < shell->line_position; i++)
					rt_kprintf("\b");
			}
			else
			{
				shell->line[shell->line_position] = ch;
				rt_kprintf("%c", ch);
			}

			ch = 0;
			shell->line_position ++;
			shell->line_curpos++;
		} /* end of device read */
	}
}
Exemplo n.º 9
0
void finsh_thread_entry(void *parameter)
{
    char ch;

    /* normal is echo mode */
    shell->echo_mode = 1;

#ifndef FINSH_USING_MSH_ONLY
    finsh_init(&shell->parser);
#endif

#ifndef RT_USING_POSIX
    /* set console device as shell device */
    if (shell->device == RT_NULL)
    {
        rt_device_t console = rt_console_get_device();
        if (console)
        {
            finsh_set_device(console->parent.name);
        }
    }
#endif

#ifdef FINSH_USING_AUTH
    /* set the default password when the password isn't setting */
    if (rt_strlen(finsh_get_password()) == 0)
    {
        if (finsh_set_password(FINSH_DEFAULT_PASSWORD) != RT_EOK)
        {
            rt_kprintf("Finsh password set failed.\n");
        }
    }
    /* waiting authenticate success */
    finsh_wait_auth();
#endif

    rt_kprintf(FINSH_PROMPT);

    while (1)
    {
        ch = finsh_getchar();

        /*
         * handle control key
         * up key  : 0x1b 0x5b 0x41
         * down key: 0x1b 0x5b 0x42
         * right key:0x1b 0x5b 0x43
         * left key: 0x1b 0x5b 0x44
         */
        if (ch == 0x1b)
        {
            shell->stat = WAIT_SPEC_KEY;
            continue;
        }
        else if (shell->stat == WAIT_SPEC_KEY)
        {
            if (ch == 0x5b)
            {
                shell->stat = WAIT_FUNC_KEY;
                continue;
            }

            shell->stat = WAIT_NORMAL;
        }
        else if (shell->stat == WAIT_FUNC_KEY)
        {
            shell->stat = WAIT_NORMAL;

            if (ch == 0x41) /* up key */
            {
#ifdef FINSH_USING_HISTORY
                /* prev history */
                if (shell->current_history > 0)
                    shell->current_history --;
                else
                {
                    shell->current_history = 0;
                    continue;
                }

                /* copy the history command */
                memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
                       FINSH_CMD_SIZE);
                shell->line_curpos = shell->line_position = strlen(shell->line);
                shell_handle_history(shell);
#endif
                continue;
            }
            else if (ch == 0x42) /* down key */
            {
#ifdef FINSH_USING_HISTORY
                /* next history */
                if (shell->current_history < shell->history_count - 1)
                    shell->current_history ++;
                else
                {
                    /* set to the end of history */
                    if (shell->history_count != 0)
                        shell->current_history = shell->history_count - 1;
                    else
                        continue;
                }

                memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
                       FINSH_CMD_SIZE);
                shell->line_curpos = shell->line_position = strlen(shell->line);
                shell_handle_history(shell);
#endif
                continue;
            }
            else if (ch == 0x44) /* left key */
            {
                if (shell->line_curpos)
                {
                    rt_kprintf("\b");
                    shell->line_curpos --;
                }

                continue;
            }
            else if (ch == 0x43) /* right key */
            {
                if (shell->line_curpos < shell->line_position)
                {
                    rt_kprintf("%c", shell->line[shell->line_curpos]);
                    shell->line_curpos ++;
                }

                continue;
            }
        }

        /* handle CR key */
        if (ch == '\0') continue;
        /* handle tab key */
        else if (ch == '\t')
        {
            int i;
            /* move the cursor to the beginning of line */
            for (i = 0; i < shell->line_curpos; i++)
                rt_kprintf("\b");

            /* auto complete */
            shell_auto_complete(&shell->line[0]);
            /* re-calculate position */
            shell->line_curpos = shell->line_position = strlen(shell->line);

            continue;
        }
        /* handle backspace key */
        else if (ch == 0x7f || ch == 0x08)
        {
            /* note that shell->line_curpos >= 0 */
            if (shell->line_curpos == 0)
                continue;

            shell->line_position--;
            shell->line_curpos--;

            if (shell->line_position > shell->line_curpos)
            {
                int i;

                rt_memmove(&shell->line[shell->line_curpos],
                           &shell->line[shell->line_curpos + 1],
                           shell->line_position - shell->line_curpos);
                shell->line[shell->line_position] = 0;

                rt_kprintf("\b%s  \b", &shell->line[shell->line_curpos]);

                /* move the cursor to the origin position */
                for (i = shell->line_curpos; i <= shell->line_position; i++)
                    rt_kprintf("\b");
            }
            else
            {
                rt_kprintf("\b \b");
                shell->line[shell->line_position] = 0;
            }

            continue;
        }

        /* handle end of line, break */
        if (ch == '\r' || ch == '\n')
        {
#ifdef FINSH_USING_HISTORY
            shell_push_history(shell);
#endif

#ifdef FINSH_USING_MSH
            if (msh_is_used() == RT_TRUE)
            {
                if (shell->echo_mode)
                    rt_kprintf("\n");
                msh_exec(shell->line, shell->line_position);
            }
            else
#endif
            {
#ifndef FINSH_USING_MSH_ONLY
                /* add ';' and run the command line */
                shell->line[shell->line_position] = ';';

                if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
                else
                    if (shell->echo_mode) rt_kprintf("\n");
#endif
            }

            rt_kprintf(FINSH_PROMPT);
            memset(shell->line, 0, sizeof(shell->line));
            shell->line_curpos = shell->line_position = 0;
            continue;
        }

        /* it's a large line, discard it */
        if (shell->line_position >= FINSH_CMD_SIZE)
            shell->line_position = 0;

        /* normal character */
        if (shell->line_curpos < shell->line_position)
        {
            int i;

            rt_memmove(&shell->line[shell->line_curpos + 1],
                       &shell->line[shell->line_curpos],
                       shell->line_position - shell->line_curpos);
            shell->line[shell->line_curpos] = ch;
            if (shell->echo_mode)
                rt_kprintf("%s", &shell->line[shell->line_curpos]);

            /* move the cursor to new position */
            for (i = shell->line_curpos; i < shell->line_position; i++)
                rt_kprintf("\b");
        }
        else
        {
            shell->line[shell->line_position] = ch;
            if (shell->echo_mode)
                rt_kprintf("%c", ch);
        }

        ch = 0;
        shell->line_position ++;
        shell->line_curpos++;
        if (shell->line_position >= FINSH_CMD_SIZE)
        {
            /* clear command line */
            shell->line_position = 0;
            shell->line_curpos = 0;
        }
    } /* end of device read */
}