/** Kinda deprecated but well, you can't have everything */
char*message_receive(lsocket*sck){
	lpacket*pck=packet_receive(sck);
	char*msg=malloc(sizeof(char)*strlen(pck->message));
	strcpy(pck->message,msg);
	packet_drop(pck);
	return msg;
}
Exemple #2
0
/** Have a handshake with the server
 * @param main_socket The server socket, used to initiate the handshake
 * @param sockets The newly created sockets
 * @return -1 if the communication cannot be established, 1 otherwise
 */
int handshake(lsocket*main_socket,lsocket**sockets){
	char message[SIZE_BUFFER*2];
	lpacket* feedback;
	int ret_code;
	
	/* Forging message */
	sprintf(message,"%s:%s\n",sockets[0]->addr,sockets[1]->addr); 
	
	/* Sending to server */
	if (verbose) printf("The following message will be send to the server:\n    %s",message);
	socket_message_send(main_socket,msg_text,message);
	if (verbose) {printf("Waiting for server response...");fflush(stdout);}
	
	/* Handshake received */
	feedback=packet_receive(sockets[0]); ret_code=feedback->type;
	if (verbose) printf("Received !\n");
	
	/* Clean */
	packet_drop(feedback);
	close_socket(main_socket,0);
	
	/* Return */
	if (ret_code==msg_recv) return 1;
	else return -1;
}
Exemple #3
0
/** Analyse user requests from stdin
 * @return 0 if no request is done, 1 otherwise
 */
int user_request(lsocket**sockets){
	char message[SIZE_BUFFER];
	lpacket*pck;
	
	/* Read user imput */
	printf("Awaiting request > ");
	fgets(message,SIZE_BUFFER,stdin);
	
	/* Process request */
	if (strlen(message)<2) {printf("No requests sent, shutting down...\n"); return 0;}
	
	/* Exchange message with the server */
	message_send(sockets[1],msg_text,message);
	pck=packet_receive(sockets[0]);
	
	if (pck->type>msg_errors) {
		printf("[Server] Error (%d): %s\n",pck->type,pck->message);
		self_terminate();
	}
	if (pck->type>msg_errors) {
		printf("[Server] Warning (%d): %s\n",pck->type,pck->message);
		return -1;
	}
	
	/* Display it */
	printf("The server answered: %s\n",pck->message);
	return 1;
}
static int	auth_process(int sock_fd, t_auth_state *state)
{
  char		buff[PACKET_BUFF_SIZE];
  t_cmd		cmd;
  char		**args;

  if ((packet_receive(sock_fd, buff) == 0) ||
      ((args = my_str_split(buff, WORD_SEPS)) == NULL ||
       my_wordtab_count((const char **)args) < 1))
    return (0);
  if ((get_cmd(args[0], &cmd) == 0) ||
      !is_auth_cmd_allowed(args[0]))
    send_msg_response(sock_fd, "530", NULL);
  else if (strcasecmp(cmd.command, "PASS") == 0 && *state == NONE)
    send_msg_response(sock_fd, "530", NULL);
  else if (cmd.execute(sock_fd, (const char **)args))
    {
      if (strcasecmp(cmd.command, "USER") == 0 && *state != NAME_STEP)
	*state = NAME_STEP;
      else if (strcasecmp(cmd.command, "PASS") == 0 && *state == NAME_STEP)
	*state = SUCCESS;
      return (my_free_wordtab(args), 1);
    }
  return (my_free_wordtab(args), 0);
}
/*
 * The servers main dispatch loop for incoming requests using SSL over TCP
 */
static DWORD server_dispatch( Remote * remote )
{
	LONG result     = ERROR_SUCCESS;
	Packet * packet = NULL;
	THREAD * cpt    = NULL;

	dprintf( "[DISPATCH] entering server_dispatch( 0x%08X )", remote );

	// Bring up the scheduler subsystem.
	result = scheduler_initialize( remote );
	if( result != ERROR_SUCCESS )
		return result;

	while( TRUE )
	{
		if( event_poll( serverThread->sigterm, 0 ) )
		{
			dprintf( "[DISPATCH] server dispatch thread signaled to terminate..." );
			break;
		}

		result = server_socket_poll( remote, 100 );
		if( result > 0 )
		{
			result = packet_receive( remote, &packet );
			if( result != ERROR_SUCCESS ) {
				dprintf( "[DISPATCH] packet_receive returned %d, exiting dispatcher...", result );		
				break;
			}

			cpt = thread_create( command_process_thread, remote, packet );
			if( cpt )
			{
				dprintf( "[DISPATCH] created command_process_thread 0x%08X, handle=0x%08X", cpt, cpt->handle );
				thread_run( cpt );
			}
		}
		else if( result < 0 )
		{
			dprintf( "[DISPATCH] server_socket_poll returned %d, exiting dispatcher...", result );
			break;
		}
	}

	dprintf( "[DISPATCH] calling scheduler_destroy..." );
	scheduler_destroy();

	dprintf( "[DISPATCH] calling command_join_threads..." );
	command_join_threads();

	dprintf( "[DISPATCH] leaving server_dispatch." );

	return result;
}
Exemple #6
0
void packet_do_handle()
{
	if(packet_receive(&inp, PACKET_INBOUND_START) == PACKET_STAT_OK) {
		if(packet_process_received(&packet_handlers, &inp) == PACKET_STAT_ERR_UNKPACK) {
			send_status_packet(PACKET_RETURN_INVALID_PACKET);
		}
	}
	else {
		send_status_packet(PACKET_RETURN_BAD_PACKET);
	}
}
/** [Deprecated] Initiate an exchange
 * Send a message, wait for a correct answer 
 * @param sck_send Socket used for sending
 * @param type_message_send Type of the sended message
 * @param msg The sended message
 * @param sck_recv Socket used for reception
 * @param type_message_recv Type expected for reception
 */
char*message_exchange(lsocket*sck_send,msg_type type_message_send,char*msg,lsocket*sck_recv,msg_type type_message_recv){
	int count=KEEP_ALIVE; /** <Time to keep-alive connection */
	lpacket*pck; char*answer;
	
	/* Force good formated answer */
	if (verbose>1) {printf("Awaiting answer...");fflush(stdout);}
	do{
		socket_message_send(sck_send,type_message_send,msg);
		if (KEEP_ALIVE-count) sleep(LATENCY); /* [ILL IMPLEMENTED] Find a damn smaller function */
		pck=packet_receive(sck_recv);
		if (verbose>1) {printf("%c",pck->type==msg_recv?'*':'.');fflush(stdout);}
		if (!count--) {printf("\n");OUT("Server didn't sent expected message")};
	} while (pck->type!=type_message_recv);
	if (verbose>1) printf("\nServer replied !\n");
	/* Copy answer */
	answer=malloc(sizeof(char)*strlen(pck->message));
	strcpy(answer,pck->message);
	
	/* Free it and return */
	packet_drop(pck);
	return answer;
}
/*
 * The servers main dispatch loop for incoming requests using SSL over TCP
 */
static DWORD server_dispatch_http_wininet( Remote * remote )
{
	LONG result     = ERROR_SUCCESS;
	Packet * packet = NULL;
	THREAD * cpt    = NULL;
	URL_COMPONENTS bits;
	DWORD ecount = 0;
	DWORD delay = 0;
	char tmpHostName[512];
	char tmpUrlPath[1024];

	if (global_expiration_timeout > 0) 
		remote->expiration_time  = current_unix_timestamp() + global_expiration_timeout;
	else
		remote->expiration_time = 0;
	
	remote->comm_timeout     = global_comm_timeout;
	remote->start_time       = current_unix_timestamp();
	remote->comm_last_packet = current_unix_timestamp();
	
	// Allocate the top-level handle
	if (!strcmp(global_meterpreter_proxy,"METERPRETER_PROXY")) {
		remote->hInternet = InternetOpen(global_meterpreter_ua, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	}
	else {
		remote->hInternet = InternetOpen(global_meterpreter_ua, INTERNET_OPEN_TYPE_PROXY, global_meterpreter_proxy, NULL, 0);
	}	if (!remote->hInternet) {
		dprintf("[DISPATCH] Failed InternetOpen: %d", GetLastError());
		return 0;
	}
	dprintf("[DISPATCH] Configured hInternet: 0x%.8x", remote->hInternet);

	
	// The InternetCrackUrl method was poorly designed...
	memset(tmpHostName, 0, sizeof(tmpHostName));
	memset(tmpUrlPath, 0, sizeof(tmpUrlPath));

	memset(&bits, 0, sizeof(bits));
	bits.dwStructSize = sizeof(bits);
	bits.dwHostNameLength  = sizeof(tmpHostName) -1;
	bits.lpszHostName      = tmpHostName;
	bits.dwUrlPathLength   = sizeof(tmpUrlPath) -1;
	bits.lpszUrlPath       = tmpUrlPath;

	InternetCrackUrl(remote->url, 0, 0, &bits);

	remote->uri = _strdup(tmpUrlPath);

	dprintf("[DISPATCH] Configured URL: %s", remote->uri);
	dprintf("[DISPATCH] Host: %s Port: %u", tmpHostName, bits.nPort);

	// Allocate the connection handle
	remote->hConnection = InternetConnect(remote->hInternet, tmpHostName, bits.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
	if (!remote->hConnection) {
		dprintf("[DISPATCH] Failed InternetConnect: %d", GetLastError());
		return 0;
	}
	dprintf("[DISPATCH] Configured hConnection: 0x%.8x", remote->hConnection);

	//authentication
	if (!(strcmp(global_meterpreter_proxy_username, "METERPRETER_USERNAME_PROXY") == 0))
	{
		InternetSetOption(remote->hConnection, INTERNET_OPTION_PROXY_USERNAME, global_meterpreter_proxy_username, (DWORD)strlen(global_meterpreter_proxy_username)+1);
		InternetSetOption(remote->hConnection, INTERNET_OPTION_PROXY_PASSWORD, global_meterpreter_proxy_password, (DWORD)strlen(global_meterpreter_proxy_password)+1);
		dprintf("[DISPATCH] Proxy authentication configured : %s/%s", global_meterpreter_proxy_username, global_meterpreter_proxy_password);
	}

	// Bring up the scheduler subsystem.
	result = scheduler_initialize( remote );
	if( result != ERROR_SUCCESS )
		return result;

	while( TRUE )
	{
		if (remote->comm_timeout != 0 && remote->comm_last_packet + remote->comm_timeout < current_unix_timestamp()) {
			dprintf("[DISPATCH] Shutting down server due to communication timeout");
			break;
		}

		if (remote->expiration_time != 0 && remote->expiration_time < current_unix_timestamp()) {
			dprintf("[DISPATCH] Shutting down server due to hardcoded expiration time");
			dprintf("Timestamp: %u  Expiration: %u", current_unix_timestamp(), remote->expiration_time);
			break;
		}

		if( event_poll( serverThread->sigterm, 0 ) )
		{
			dprintf( "[DISPATCH] server dispatch thread signaled to terminate..." );
			break;
		}

		dprintf("[DISPATCH] Reading data from the remote side...");
		result = packet_receive( remote, &packet );
		if( result != ERROR_SUCCESS ) {

			// Update the timestamp for empty replies
			if (result == ERROR_EMPTY) 
				remote->comm_last_packet = current_unix_timestamp();

			if (ecount < 10)
				delay = 10 * ecount;
			else 
				delay = 100 * ecount;
			
			ecount++;

			dprintf("[DISPATCH] no pending packets, sleeping for %dms...", min(10000, delay));
			Sleep( min(10000, delay) );
			continue;
		}

		remote->comm_last_packet = current_unix_timestamp();

		// Reset the empty count when we receive a packet
		ecount = 0;

		dprintf("[DISPATCH] Returned result: %d", result);

		cpt = thread_create( command_process_thread, remote, packet );
		if( cpt )
		{
			dprintf( "[DISPATCH] created command_process_thread 0x%08X, handle=0x%08X", cpt, cpt->handle );
			thread_run( cpt );
		}	
	}

	// Close WinInet handles
	InternetCloseHandle(remote->hConnection);
	InternetCloseHandle(remote->hInternet);

	dprintf( "[DISPATCH] calling scheduler_destroy..." );
	scheduler_destroy();

	dprintf( "[DISPATCH] calling command_join_threads..." );
	command_join_threads();

	dprintf( "[DISPATCH] leaving server_dispatch." );

	return result;
}
Exemple #9
0
static void *thread_main_loop(void *_state)
{
	struct thread_state *state = (struct thread_state *)_state;
	struct packet *pkt = NULL;
	sigset_t set;
#ifdef HAKA_MEMCHECK
	int64 pkt_count=0;
	const int mem_rate=10;
#endif

	thread_setid(state->thread_id);

	if (!state->pool->single) {
		/* Block all signal to let the main thread handle them */
		sigfillset(&set);
		sigdelset(&set, SIGSEGV);
		sigdelset(&set, SIGILL);
		sigdelset(&set, SIGFPE);

		if (!thread_sigmask(SIG_BLOCK, &set, NULL)) {
			LOG_FATAL(core, "%s", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		if (!timer_init_thread()) {
			LOG_FATAL(core, "%s", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		/* To make sure we can still cancel even if some thread are locked in
		 * infinite loops */
		if (!thread_setcanceltype(THREAD_CANCEL_ASYNCHRONOUS)) {
			LOG_FATAL(core, "%s", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		if (!init_thread_lua_state(state)) {
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}
	}

	state->engine = engine_thread_init(state->lua->L, state->thread_id);
	engine_thread_update_status(state->engine, THREAD_RUNNING);

	packet_init(state->capture);

	if (!state->pool->single) {
		if (!barrier_wait(&state->pool->thread_start_sync)) {
			LOG_FATAL(core, "%s", clear_error());
			state->state = STATE_ERROR;
			engine_thread_update_status(state->engine, THREAD_DEFUNC);
			return NULL;
		}
	}

	if (!state->pool->single) {
		if (!barrier_wait(&state->pool->thread_sync)) {
			LOG_FATAL(core, "%s", clear_error());
			state->state = STATE_ERROR;
			engine_thread_update_status(state->engine, THREAD_DEFUNC);
			return NULL;
		}
	}

	lua_state_trigger_haka_event(state->lua, "started");

	engine_thread_update_status(state->engine, THREAD_WAITING);

	while (packet_receive(state->engine, &pkt) == 0) {
		engine_thread_update_status(state->engine, THREAD_RUNNING);

		/* The packet can be NULL in case of failure in packet receive */
		if (pkt) {
			filter_wrapper(state, pkt);
			pkt = NULL;
		}

		lua_state_runinterrupt(state->lua);
		engine_thread_check_remote_launch(state->engine);

		if (state->pool->attach_debugger > state->attach_debugger) {
			luadebug_debugger_start(state->lua->L, true);
			state->attach_debugger = state->pool->attach_debugger;
		}

		engine_thread_update_status(state->engine, THREAD_WAITING);

#ifdef HAKA_MEMCHECK
		if (((pkt_count++) % mem_rate) == 0) {
			size_t vmsize, rss;
			if (!get_memory_size(&vmsize, &rss)) {
				LOG_ERROR(core, "cannot get memory report: %s", clear_error());
			}
			else {
				const size_t luasize = lua_gc(state->lua->L, LUA_GCCOUNT, 0);
				LOG_DEBUG(core, "memory report: thread=%d vmsize=%zd rsssize=%zd luasize=%zd",
						engine_thread_id(state->engine), vmsize, rss, luasize);
			}
		}
#endif

		if (state->pool->stop) {
			break;
		}
	}

	state->state = STATE_FINISHED;
	engine_thread_update_status(state->engine, THREAD_STOPPED);

	return NULL;
}
Exemple #10
0
/***************************************************************************//**
*
* uart_update - 从串口进行升级
*
* @param void
*
* @retval true  成功
* @retval false 失败
*
*******************************************************************************/
STATUS uart_update(void)
{
    uint32 i, startAddress, transferSize = 0;
    uint8 size;
    uint8 status;
    uint8 cmd, data[MAX_BUF_SIZE];

    uart_printf("Press ESC to upgrade from serial port ");

    // 检测是否要从串口进行升级
    if (!escKeyDetect()) return (OK);

    uart_printf("Receiving data ..");

    // 过滤多余按键或串口切换产生的错误字节
    while (!packet_hello())
    {
    }

    startAddress = 0xffffffff;

    status = COMMAND_RET_SUCCESS;
    while (true)
    {
        // 如果未正确接收报文,放弃处理
        if (!packet_receive(&cmd, data, &size))
        {
            packet_nak();
            continue;
        }

        // 根据命令字进行处理
        switch(cmd)
        {
        case COMMAND_PING: // 测试连接
            status = COMMAND_RET_SUCCESS;

            // 返回确认包
            packet_ack();

            break;

        case COMMAND_DOWNLOAD: // 开始下载
            status = COMMAND_RET_SUCCESS;
            do
            {
                // 检查报文长度
                if (size != 8)
                {
                    status = COMMAND_RET_INVALID_CMD;

                    break;
                }

                // 起始地址
                startAddress = (data[0] << 24)
                               | (data[1] << 16)
                               | (data[2] <<  8)
                               |  data[3];
                /* 起始地址必须为0,由各BootLoader自行决定写入位置 */
                if (startAddress != 0u)
                {
                    status = COMMAND_RET_INVALID_CMD;
                    break;
                }
                startAddress = APP_START_ADDRESS;
                // 下载字节数
                transferSize = (data[4] << 24)
                               | (data[5] << 16)
                               | (data[6] <<  8)
                               |  data[7];

                // 检查写入空间
                if (!iflash_spaceCheck(startAddress, transferSize))
                {
                    status = COMMAND_RET_INVALID_PARA;

                    break;
                }

                // 清除中断状态
                iflash_errorClear();

                // 按块擦除将要更新的地址区间
                for (i = startAddress; i < startAddress + transferSize; i += FLASH_PAGE_SIZE)
                    iflash_erase(i);

                // 检查中断状态,如果出现错误,则设置对应状态
                if (iflash_errorCheck())
                    status = COMMAND_RET_FLASH_FAIL;
            }
            while(false);

            if (status != COMMAND_RET_SUCCESS)
                transferSize = 0;

            // 确认报文已得到处理
            packet_ack();

            break;

        case COMMAND_GET_STATUS: // 获取状态
            // 返回确认包
            packet_ack();

            // 返回当前状态
            packet_status(status);

            break;

        case COMMAND_SEND_DATA: // 数据
            status = COMMAND_RET_SUCCESS;

            // 注意:后台程序应保证size按字对齐,否则写入结果无法预料
            // 检查是否还有数据未写入
            if (transferSize >= size)
            {
                iflash_write(startAddress, data, size);
                if (iflash_errorCheck())
                    status = COMMAND_RET_FLASH_FAIL;
                else
                {
                    transferSize -= size;
                    startAddress += size;
                }
            }
            else status = COMMAND_RET_INVALID_PARA;

            // 返回确认包
            packet_ack();

            break;

        case COMMAND_RESET: // 复位
            // 返回确认包
            packet_ack();

            // 等待UART完成发送
            uart_flush();

            delay(524288);

            // 写入注册码及复位请求
            HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ);

            // 死循环
            while(true)
            {
            }
        default: // 未知命令
            // 返回确认包
            packet_ack();

            // 状态设为未知命令
            status = COMMAND_RET_UNKNOWN_CMD;
        }
    }
}
Exemple #11
0
static void *thread_main_loop(void *_state)
{
	struct thread_state *state = (struct thread_state *)_state;
	struct packet *pkt = NULL;
	sigset_t set;

	thread_setid(state->thread_id);

	if (!state->pool->single) {
		/* Block all signal to let the main thread handle them */
		sigfillset(&set);
		sigdelset(&set, SIGSEGV);
		sigdelset(&set, SIGILL);
		sigdelset(&set, SIGFPE);

		if (!thread_sigmask(SIG_BLOCK, &set, NULL)) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		if (!timer_init_thread()) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		/* To make sure we can still cancel even if some thread are locked in
		 * infinite loops */
		if (!thread_setcanceltype(THREAD_CANCEL_ASYNCHRONOUS)) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		if (!init_thread_lua_state(state)) {
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}
	}

	state->engine = engine_thread_init(state->lua->L, state->thread_id);
	engine_thread_update_status(state->engine, THREAD_RUNNING);

	packet_init(state->capture);

	if (!state->pool->single) {
		if (!barrier_wait(&state->pool->thread_start_sync)) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			state->state = STATE_ERROR;
			engine_thread_update_status(state->engine, THREAD_DEFUNC);
			return NULL;
		}
	}

	if (!state->pool->single) {
		if (!barrier_wait(&state->pool->thread_sync)) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			state->state = STATE_ERROR;
			engine_thread_update_status(state->engine, THREAD_DEFUNC);
			return NULL;
		}
	}

	lua_state_trigger_haka_event(state->lua, "started");

	engine_thread_update_status(state->engine, THREAD_WAITING);

	while (packet_receive(&pkt) == 0) {
		engine_thread_update_status(state->engine, THREAD_RUNNING);

		/* The packet can be NULL in case of failure in packet receive */
		if (pkt) {
			filter_wrapper(state, pkt);
			pkt = NULL;
		}

		lua_state_runinterrupt(state->lua);
		engine_thread_check_remote_launch(state->engine);

		if (state->pool->attach_debugger > state->attach_debugger) {
			luadebug_debugger_start(state->lua->L, true);
			state->attach_debugger = state->pool->attach_debugger;
		}

		engine_thread_update_status(state->engine, THREAD_WAITING);

		if (state->pool->stop) {
			break;
		}
	}

	state->state = STATE_FINISHED;
	engine_thread_update_status(state->engine, THREAD_STOPPED);

	return NULL;
}
Exemple #12
0
UINT32 cmd_stbid(unsigned int argc, unsigned char *argv[])
{
	UINT8 i = 0, j = 0, ch = 0xff;
	UINT8 *_stbid_flag = "SRI";
	INT32 _stbid_flag_len = 3;
	UINT8 _serial_data[1024]; // max receive 1KB data
	UINT32 timeout = 1000, stbid_offset = STB_HWINFO_SERIAL_OFF, _stbid_crc = 0, _stbid_len = 0, _serial_len = 0, _crc = 0, _crc_pos = 0;
	UINT8 *buffer = NULL;
	UINT32 nReturn = SUCCESS;
	UINT32 nPacketNum = 0;
	PACKET packet;
	UINT32 tick = osal_get_tick();
	UINT8 retry_num = 5, _tr_num = 5;
	ID _task_id = g_com_ash_id;
	
	osal_task_dispatch_off();	
	
	SendStatusPacket(COMMAND_STATUS_OK,  0);
	pan_display(g_pan_dev, "Stb-", 4);
	
RETRY:	
	_tr_num = 5;
	
	//transfer data
	MEMSET(&packet, 0, sizeof(PACKET));
	
	nReturn = packet_receive(&packet, 5 * 1000);
	if(SUCCESS != nReturn)
	{
		SERIAL_DEBUG("receive packet fail!\n");	
		retry_num--;
		goto RETURN;
	}
	
	if(packet.packet_type == PACKET_DATA)
	{	
		_serial_len = packet.packet_length-4;
		MEMCPY(_serial_data, packet.data_buffer+4, packet.packet_length-4);
	}
	else
	{
		SERIAL_DEBUG("receive %d packet, ignore!\n", packet.packet_type);
		retry_num--;
		goto RETURN;
	}
	
	SERIAL_DEBUG("stbid get data total len %d finish, data: \n", _serial_len);
	for(i=0; i<_serial_len; i++)
	{
		SERIAL_DEBUG("%c", _serial_data[i]);
	}
	SERIAL_DEBUG("\n");
	
	pan_display(g_pan_dev, "GET", 4);
	if((_serial_data[0] != _stbid_flag[0]) || (_serial_data[1] != _stbid_flag[1]) || (_serial_data[2] != _stbid_flag[2])) // received flag tag
	{
		SERIAL_DEBUG("Error: SRI flag missing!\n");	
		retry_num--;
		goto RETURN;
	}
	
	pan_display(g_pan_dev, "FLAG", 4);
	_stbid_len = _serial_len-4-8;
	if(_stbid_len > STB_HWINFO_MAC_OFF)
	{
		SERIAL_DEBUG("Error: stbid len %d != [%d], please resend cmd!\n", _stbid_len, STB_HWINFO_MAC_OFF);
		retry_num--;
		goto RETURN;
	}
	
	pan_display(g_pan_dev, "LENG", 4);
	
	// do crc check
	_crc_pos = _stbid_flag_len+1+_stbid_len;
	_stbid_crc = 0;
	for(i=0; i<8; i++)
	{
		_stbid_crc |= (((_serial_data[_crc_pos+i]>'9') ? (_serial_data[_crc_pos+i]-'A'+10) : (_serial_data[_crc_pos+i]-'0'))<<((7-i)*4));
	}
	
	_crc = MG_Table_Driven_CRC(0xFFFFFFFF, _serial_data, _crc_pos);
	if(_stbid_crc != _crc)
	{
		// fail, need re-trans
		SERIAL_DEBUG("stbid crc fail, calcu = 0x%x!\n", _crc);
		retry_num--;
		goto RETURN;
	}
	
	pan_display(g_pan_dev, "CRC", 4);
	// burn code, enable drive auto-erase
	for(i=0; i<(STB_HWINFO_OUI_OFF-STB_HWINFO_MAC_OFF); i++) // init mac
	{
		ch = _serial_data[STB_HWINFO_MAC_OFF+4-12+i*2];
		_serial_data[i+STB_HWINFO_MAC_OFF+4] = (((ch>'9') ? ((ch>='a') ? (ch-'a'+10) : (ch-'A'+10)) : (ch-'0'))<<4);
		ch = _serial_data[STB_HWINFO_MAC_OFF+4-12+i*2+1];
		_serial_data[i+STB_HWINFO_MAC_OFF+4] |= ((ch>'9') ? ((ch>='a') ? (ch-'a'+10) : (ch-'A'+10)) : (ch-'0'));
	}
	
	buffer = MALLOC(64*1024);
	if(buffer == NULL)
	{
		SDBBP();
	}
	
	sto_io_control(g_sto_dev, STO_DRIVER_SECTOR_BUFFER, (UINT32)buffer);
	sto_io_control(g_sto_dev, STO_DRIVER_SET_FLAG, STO_FLAG_AUTO_ERASE|STO_FLAG_SAVE_REST);
	
	SERIAL_DEBUG("Now burn stbid: ");	
	for(i=0; i<STB_HWINFO_OUI_OFF; i++)
	{
		SERIAL_DEBUG("%c", _serial_data[i+_stbid_flag_len+1]);
	}
	SERIAL_DEBUG("\n");
	
	sto_put_data(g_sto_dev, STB_HWINFO_BASE_ADDR, &_serial_data[_stbid_flag_len+1], STB_HWINFO_OUI_OFF);	
	if(buffer)
	{
		FREE(buffer);
		buffer = NULL;
		sto_io_control(g_sto_dev, STO_DRIVER_SECTOR_BUFFER, 0);
		sto_io_control(g_sto_dev, STO_DRIVER_SET_FLAG, 0);
	}
	
	if(g_stb_hwinfo != NULL)
	{
		FREE(g_stb_hwinfo);
		g_stb_hwinfo = NULL;
	}
	
	pan_display(g_pan_dev, "-tr-", 4);
	SERIAL_DEBUG("stbid finish, task %d deleted!\n", g_com_ash_id);
	SERIAL_DEBUG("cmd_stbid takes %dms\n", osal_get_tick()-tick);
	retry_num = 0;

RESEND:	
	SendStatusPacket(COMMAND_STATUS_DONE, 0);
	MEMSET(&packet, 0, sizeof(PACKET));
	osal_task_sleep(100);
	
	nReturn = packet_receive(&packet, 5 * 1000);
	if((SUCCESS != nReturn) || (packet.packet_type != PACKET_STATUS))
	{
		if(_tr_num-- > 0)
		{
			SERIAL_DEBUG("stbid finish, but signal send fail, now re-send!\n");
			goto RESEND;
		}
		else
		{
			pan_display(g_pan_dev, "dStb", 4); // done, but notice fail!
		}
	}
	else
	{
		pan_display(g_pan_dev, "-Stb", 4); // done, all ok!
	}
	
RETURN:
	if(retry_num >0)
	{
		SendStatusPacket(COMMAND_STATUS_ERROR, 0);
		goto RETRY;
	}
	else
	{
		SERIAL_DEBUG("error, please redo!\n");
		api_set_com_check_flag(COM_MONITOR_CHECK_STBID);
	}
	
	g_com_ash_id = INVALID_ID;
	osal_task_dispatch_on();
	osal_task_delete(_task_id);
}