#include "Neptune.h"
#include "Platinum.h"
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h> /* definations of sa_family structre,htons,INADDR_ANY,... */
#include <arpa/inet.h> /* name ip format */
#include <sys/types.h> /*give the defination of pid_t*/
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h> /* isspace() */
#define BUFFER_MAX 1024 /* input buffer for commands */
#define TOKEN_MAX 8 /* max number of arguments in buffer */
#define REPLY_MAX 256 /* largest reply allowed */
#define MAX_QUE_CONN_NM 10
NPT_SET_LOCAL_LOGGER("platinum.media.server.file")
//example:NPT_Debug("ERROR: failed to load entity (%d)\n", result);
int sockfd;
static NPT_Flags deviceStartFlag = 0; //服务启动状态为1,服务停止则状态为0
PLT_UPnP upnp;
PLT_DeviceHostReference device;
int init_sock()
{
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
NPT_LOG_INFO("baojinyu---------------create socket error! \n");
exit(1);
}
NPT_LOG_INFO("baojinyu---------------create socket successfully .\n");
return 0;
}
int init_device()
{
device = new PLT_FileMediaServer(
"/data/local/1.3gp",//"/data/local/if.mp3",
"Platinum UPnP Media Server",
false,
"SAMEDEVICEGUID", // NULL for random ID
(NPT_UInt16)1194);
NPT_List<NPT_IpAddress> list;
NPT_CHECK_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(list));
NPT_String ip = list.GetFirstItem()->ToString();
device->m_ModelDescription = "Platinum File Media Server";
device->m_ModelURL = "http://www.plutinosoft.com/";
device->m_ModelNumber = "1.0";
device->m_ModelName = "Platinum File Media Server";
device->m_Manufacturer = "Plutinosoft";
device->m_ManufacturerURL = "http://www.plutinosoft.com/";
upnp.AddDevice(device);
NPT_CHECK_SEVERE(upnp.Start());//Just for test.
return 0;
}
int init()
{
init_sock();
init_device();
return 0;
}
//the following are commands.
static int HandleCmd_dmsStartStop(char **arg, char reply[REPLY_MAX])
{
if (!deviceStartFlag){
//start service
NPT_LOG_INFO("baojinyu------------socket cmd Start。");
NPT_CHECK_SEVERE(upnp.Start());
NPT_LOG_INFO("baojinyu------------upnp Start success!");
deviceStartFlag = 1;
}
else{
//stop service
NPT_LOG_INFO("baojinyu------------socket cmd stop。");
upnp.Stop();
NPT_LOG_INFO("baojinyu------------upnp stop success!");
deviceStartFlag = 0;
}
return deviceStartFlag;
}
struct cmdinfo {
const char *name;
unsigned numargs;
int (*func)(char **arg, char reply[REPLY_MAX]);
};
struct cmdinfo cmds[] = {
//{ "isMouse", 1, isMouse },
//{ "mousePrecision", 1, mousePrecision },
{ "dmsStartStop", 0, HandleCmd_dmsStartStop },
//{ "mediaManage", 1, HandleCmd_mediaManage },
//{ "serverConfig", 1, HandleCmd_serverConfig },
};
static int readx(int fd, void *_buf, int count)
{
char *buf =(char *) _buf;
int n = 0, r;
if (count < 0) return -1;
while (n < count) {
r = read(fd, buf + n, count - n);
if (r < 0) {
if (errno == EINTR) continue;
NPT_LOG_INFO("read error\n");
return -1;
}
if (r == 0) {
NPT_LOG_INFO("eof");
return -1; /* EOF */
}
n += r;
}
return 0;
}
static int writex(int fd, const void *_buf, int count)
{
const char *buf =(char *) _buf;
int n = 0, r;
if (count < 0) return -1;
while (n < count) {
r = write(fd, buf + n, count - n);
if (r < 0) {
if (errno == EINTR) continue;
NPT_LOG_INFO("write error");
return -1;
}
n += r;
}
return 0;
}
/* Tokenize the command buffer, locate a matching command,
* ensure that the required number of arguments are provided,
* call the function(), return the result.
*/
static int execute(int s, char cmd[BUFFER_MAX])
{
char reply[REPLY_MAX];
char *arg[TOKEN_MAX+1];
unsigned i;
unsigned n = 0;
unsigned short count, le_count;
int ret = -1;
/* default reply is "" */
reply[0] = 0;
/* n is number of args (not counting arg[0]) */
arg[0] = cmd;
while (*cmd) {
if (isspace(*cmd)) {
*cmd++ = 0;
n++;
arg[n] = cmd;
if (n == TOKEN_MAX) {
NPT_LOG_INFO("too many arguments");
goto done;
}
}
cmd++;
}
for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) {
if (!strcmp(cmds[i].name,arg[0])) {
if (n != cmds[i].numargs) {
NPT_LOG_INFO("numargs doesnot equal requires arguments ");
} else {
ret = cmds[i].func(arg + 1, reply);
}
goto done;
}
}
NPT_LOG_INFO("unsupported command");
done:
if (reply[0]) {
n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply);
} else {
n = snprintf(cmd, BUFFER_MAX, "%d", ret);
}
if (n > BUFFER_MAX) n = BUFFER_MAX;
count = n;
/* receiver expects count in little-endian order */
le_count = htole16(count);
// LOGI("reply: '%s'\n", cmd);
if (writex(s, &le_count, sizeof(le_count))) return -1;
if (writex(s, cmd, count)) return -1;
return 0;
}
int
main(int argc, char** argv)
{
//setup Neptune logging
NPT_LogManager::GetDefault().Configure("plist:.level=INFO;.handlers=ConsoleHandler;.ConsoleHandler.colors=off;.ConsoleHandler.filter=42");
NPT_LOG_INFO("baojinyu---------------media server just begin\n ");
init();
char buf[BUFFER_MAX];
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size = sizeof(struct sockaddr_in);
/* socket配置 */
bzero(&server_sockaddr, sizeof(server_sockaddr));
server_sockaddr.sin_family = AF_INET; /* 地址族 */
server_sockaddr.sin_port = htons(7933);/* 端口号 */
//server_sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");/* 系统会自动填入本机的IP地址 */
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
//bzero(&(server_sockaddr.sin_zero),8);/*填充0和struct sockaddr 同样大小*/
int i = 1; /* 允许重复使用本地地址与套接字进行绑定 */
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, (const char*)&i, sizeof(i));
//if(bind(sockfd,(struct sockaddr*)&server_sockaddr,len) < 0){
if(bind(sockfd,(struct sockaddr*)&server_sockaddr, sin_size) == -1){
NPT_LOG_INFO("baojinyu---------------Bind failure.\n ");
exit(1);
}
NPT_LOG_INFO("baojinyu--------------- Bind successfully.\n ");
/* listen for connections on a socket */
if(listen(sockfd, MAX_QUE_CONN_NM) == -1){
NPT_LOG_INFO("baojinyu--------------- Listen failure.\n ");
exit(1);
}
NPT_LOG_INFO("baojinyu--------------- Listen successfully ");
int client_fd, fd;
int result;
int readflag;
int maxfd=sockfd;
fd_set tmp_readfds;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
fd_set tmp_writefds;
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(sockfd, &writefds);
struct timeval timeout;
fd_set fdset;
while(true)
{
tmp_readfds = readfds;
tmp_writefds = writefds;
NPT_LOG_INFO("baojinyu--------------- enter while loop ");
timeout={5,0};
result = select(maxfd+1, &tmp_readfds, &tmp_writefds, NULL, &timeout);
if(result == 0)
{
NPT_LOG_INFO("baojinyu----------------------Select timeout!---no change happens.\n");
continue;
}else if(result == -1)
{
NPT_LOG_INFO("baojinyu----------------------Select failure!\n");
break;
}
NPT_LOG_INFO("baojinyu-----------------Select successfully\n");
for(fd=0; fd < FD_SETSIZE; fd++)
{
if(FD_ISSET(fd,&tmp_readfds))
{
NPT_LOG_INFO("baojinyu-----------------FD_ISSET\n");
if(fd == sockfd)
{ //服务端接收客户端连接请求
NPT_LOG_INFO("baojinyu-----------------fd == sockfd\n");
client_fd = accept(sockfd, (struct sockaddr*)&client_sockaddr, &sin_size);
sleep(1);
if(client_fd > 0)
{
if(client_fd > maxfd){
maxfd = client_fd;
}
FD_SET(client_fd,&readfds);
/*
NPT_Debug("baojinyu--accept success--------Got connection from %s, port %d,socket %d\n",
inet_ntoa(client_sockaddr.sin_addr),ntohs(client_sockaddr.sin_port),client_fd);
* */
printf("baojinyu--accept success--------Got connection from %s, port %d,socket %d\n",
inet_ntoa(client_sockaddr.sin_addr), ntohs(client_sockaddr.sin_port), client_fd);
}else {
NPT_LOG_INFO("baojinyu-----------------accept failure.\n");
break;
}
}else{
ioctl(fd,FIONREAD,&readflag);
if(readflag == 0){
NPT_LOG_INFO("baojinyu----------------readflag == 0 \n");
close(fd);
FD_CLR(fd,&readfds);
}
else{
bzero(buf, BUFFER_MAX);
//处理客户端发来的消息-read size
unsigned short count;
if (readx(fd, &count, sizeof(count))){
NPT_LOG_INFO("baojinyu-------------------failed to read size\n");
break;
}
count = letoh16(count);
if ((count < 1) || (count >= BUFFER_MAX)) {
//NPT_LOG_INFO("baojinyu-------------------count error!\n");
printf("baojinyu--------count error!--count= %d\n",count);
break;
}
if (readx(fd, buf, count)) {
NPT_LOG_INFO("baojinyu----------------failed to read command\n");
break;
}
buf[count] = 0;
if (execute(fd, buf)) break;
}
}
} //end of if(FD_ISSET(fd,&tmp_readfds))
} //end for
}
for(fd = 0; fd < FD_SETSIZE; fd++)
{
close(fd);
FD_CLR(fd,&readfds);
}
return 0;
}