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