void Session::KeyProc()
{
	char cmd[32];
	while(true)
	{
		if(_keyStatus == 0) Sleep(1000); // None
		else if(_keyStatus == 1) // MainMenu
		{
			printf("\n[L] get music list from server\n");
			printf("[V] view music list\n");
			printf("[number] play the music with number\n");
			printf("[Q] exit\n");
			printf("Your choice: ");
			scanf("%s", &cmd);

			if(cmd[0] == 'l' || cmd[0] == 'L') 
			{
				SetSendBuf(1); // ListInfo
				_keyStatus = 0;
				printf("\nDownloading the music list from server...\n\n");
			}
			else if(cmd[0] == 'v' || cmd[0] == 'V') 
			{
				if(_musicCount == 0)
				{
					SetSendBuf(1); // ListInfo
					_keyStatus = 0;
					printf("\nDownloading the music list from server...\n\n");
				}
				else
				{
					printf("\n");
					for(int i = 0; i < _musicCount; i++)
					{
						printf("[%d] %s\n", i + 1, _musicNames[i]);
					}
				}
			}
			else if(cmd[0] == 'q' || cmd[0] == 'Q') 
			{
				_alive = -1;
				break;
			}
			else
			{
				int number = atoi(cmd);
				if(number > 0 && number <= _musicCount)
				{
					_musicIndex = number - 1;
					SetSendBuf(3); // FileInfo
					_keyStatus = 0;
					printf("\nInitializing...\n\n");
				}
			}
		}
		else if(_keyStatus == 2) // PlayMenu
		{
			printf("\n[P] play\n");
			printf("[S] stop\n");
			printf("[A] pause\n");
			printf("[X] main menu\n");
			while(true)
			{
				printf("Your choice: ");
				scanf("%s", &cmd);
				if(cmd[0] == 'p' || cmd[0] == 'P') 
				{
					if(!_audio.IsAvailable())
					{
						SetSendBuf(3); // FileInfo
						_keyStatus = 0;
						while(!_audio.IsAvailable()) Sleep(500);
					}
					_audio.Play();
				}
				else if(cmd[0] == 's' || cmd[0] == 'S') 
				{
					_audio.Stop();
					SetSendBuf(3); // FileInfo
					_keyStatus = 0;
					break;
				}
				else if(cmd[0] == 'a' || cmd[0] == 'A') 
				{
					_audio.Pause();
				}
				else if(cmd[0] == 'x' || cmd[0] == 'X') 
				{
					_audio.Stop();
					_keyStatus = 1;
					break;
				}
			}
		}
	}
}
Beispiel #2
0
s32 DispatchLooper(struct NetLooper * looper, const s32 millisecond) {
    struct epoll_event * events = (struct epoll_event *)alloca(sizeof(struct epoll_event) * looper->size);
    memset(events, 0, sizeof(struct epoll_event) * looper->size);
    s32 retCount = epoll_wait(looper->fd, events, looper->size, millisecond);
    if (retCount == -1) {
        if (errno != EINTR) {
            printf("epoll_wait error %d\n", errno);
        }
        return;
    }

    if (retCount == 0)
        return;

    s32 i = 0;
    for (i = 0; i < retCount; i++) {
        s32 code;
        s32 fd;
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);

        char type = ((struct NetBase *)events[i].data.ptr)->type;
        switch (type) {
        case BNEV_ACCEPT: {
            struct NetBase * accepter = events[i].data.ptr;
            if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
                code = -1;
                OASSERT(0, "wtf");
            } else if (events[i].events & EPOLLIN) {
                memset(&addr, 0, sizeof(addr));

                s32 i = 0;
                while (i++ < 30 && (fd = accept(accepter->fd, (struct sockaddr *)&addr, &len)) >= 0) {
                    if (0 == SetNonBlocking(fd) && 0 == SetSendBuf(fd, 0) && 0 == SetNonNegal(fd)) {
                        struct NetBase * base = (struct NetBase *)MALLOC(sizeof(struct NetBase));
                        base->fd = fd;
                        base->type = BNEV_IO;
                        base->looper = NULL;
                        base->maxRecvSize = accepter->maxRecvSize;
                        base->maxSendSize = accepter->maxSendSize;
                        if (0 != (*looper->fnAccept)(accepter, base)) {
                            FreeBase(base);
                        }
                    }
                    else {
                        close(fd);
                    }
                }
            }
            break;
        }
        case BNEV_CONNECT: {
            struct NetBase * connecter = events[i].data.ptr;
            if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP))
                code = -1;
            else if (events[i].events & EPOLLOUT)
                code = 0;

            if (UnbindLooper(connecter) != 0) {
                printf("epoll add fd error %s\n", strerror(errno));
                //return;
                OASSERT(0, "wtf");
            }
            connecter->type = BNEV_IO;

            (*looper->fnConnect)(connecter, code);

            if (-1 == code)
                FreeBase(connecter);
            break;
        }
        case BNEV_IO: {
            struct NetBase * base = events[i].data.ptr;
            if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
                UnbindLooper(base);
                (*looper->fnRecv)(base, -1, NULL, 0);
                FreeBase(base);
                break;
            }

            if (events[i].events & EPOLLIN) {
                s32 res = 0;
                while (1) {
                    u32 size = 0;
                    s32 len = 0;
                    char * buf = RingBufferWrite(base->recvBuff, &size);
                    if (buf && size > 0) {
                        len = recv(base->fd, buf, size, 0);
                        if (len < 0 && errno == EAGAIN)
                            break;
                    }
                    else
                        len = -1;

                    if (len <= 0) {
                        UnbindLooper(base);
                        (*looper->fnRecv)(base, -1, NULL, 0);
                        FreeBase(base);
                        res = -1;
                        break;
                    }

                    if (-1 == (*looper->fnRecv)(base, 0, buf, len)) {
                        UnbindLooper(base);
                        FreeBase(base);
                        res = -1;
                        break;
                    }
                }

                if (-1 == res)
                    break;
            }

            if (events[i].events & EPOLLOUT) {
                if (0 != (*looper->fnSend)(base)) {
                    UnbindLooper(base);
                    FreeBase(base);
                }
            }

            break;
        }
        default:
            OASSERT(0, "wtf");
            break;
        }
    }
}
void Session::ParseData()
{
	PacketInfo* response = (PacketInfo*)_recvData;
	if(response->type == 1) // ListInfo
	{
		if(_musicNames != NULL) 
		{
			for(int i = 0; i < _musicCount; i++) 
			{
				if(_musicNames[i] != NULL) delete [] _musicNames[i];
			}
		}
		_musicCount = response->count;
		_musicNames = (char**)(new char*[_musicCount]);
		for(int i = 0; i < _musicCount; i++) _musicNames[i] = NULL;
		_musicOffset = 0;

		SetSendBuf(2, response->serialnumber); // ListBlock
	}
	else if(response->type == 2) // ListBlock
	{
		if(_musicNames == NULL)
		{
			SetSendBuf(1, response->serialnumber); // ListInfo
			return;
		}

		if(_musicOffset != _request.offset) 
		{
			SetSendBuf(2, response->serialnumber); // ListBlock
			return;
		}

		int offset = sizeof(PacketInfo);
		while(offset < _recvSize && _musicOffset < _musicCount)
		{
			ListInfo* listInfo = (ListInfo*)(_recvData + offset);
			if(listInfo->offset != _musicOffset) break;
			offset += sizeof(ListInfo);

			if(_recvSize - offset < listInfo->size) break;

			_musicNames[_musicOffset] = new char[listInfo->size];
			memcpy(_musicNames[_musicOffset], _recvData + offset, listInfo->size);
			printf("[%d] %s\n", _musicOffset + 1, _musicNames[_musicOffset]);
			_musicOffset++;
			offset += listInfo->size;
		}

		if(_musicOffset < _musicCount)
		{
			SetSendBuf(2, response->serialnumber); // ListBlock
			return;
		}

		_keyStatus = 1;
		SetSendBuf(0, response->serialnumber); // Satatus
	}
	else if(response->type == 3) // FileInfo
	{
		_fileSize = response->count;
		if(_fileSize == -1) 
		{
			printf("[%s couldn't be read\n", _musicNames[_musicIndex]);
			_keyStatus = 1;
			SetSendBuf(0, response->serialnumber); // Satatus
			return;
		}
		else if(_fileSize < 1024) printf("\n%s filesize: %d bytes\n", _musicNames[_musicIndex], _fileSize);
		else printf("\n%s filesize: %d KB\n", _musicNames[_musicIndex], _fileSize / 1024);

		_audio.Start();
		_fileOffset = 0;
		_keyStatus = 2;
		SetSendBuf(4, response->serialnumber); // FileBlock
	}
	else if(response->type == 4) // FileBlock
	{
		if(_audio.IsAvailable()) _keyStatus = 2;

		_blockSize = _recvSize - sizeof(PacketInfo);
		if(_fileOffset != response->offset) 
		{
			SetSendBuf(4, response->serialnumber); // FileBlock
			return;
		}

		_dataQueue.AddQueue(_recvData + sizeof(PacketInfo), _blockSize);
		_fileOffset += _blockSize;

		if(_fileOffset < _fileSize)
		{
			SetSendBuf(4, response->serialnumber); // ListBlock
			return;
		}

		_audio.Done();
		SetSendBuf(0, response->serialnumber); // Satatus
	}
}