mirror of https://github.com/sipwise/sems.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
5.3 KiB
277 lines
5.3 KiB
#include "AmCtrlInterface.h"
|
|
#include "AmUtils.h"
|
|
#include "AmConfig.h"
|
|
#include "log.h"
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/poll.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
AmCtrlInterface* AmCtrlInterface::getNewCtrl()
|
|
{
|
|
// if(AmConfig::SendMethod == "fifo"){
|
|
// return new AmFifoCtrlInterface(p);
|
|
// }
|
|
// else if(AmConfig::SendMethod == "unix_socket"){
|
|
// return new AmUnixCtrlInterface(p);
|
|
// }
|
|
// ERROR("unknown send method\n");
|
|
// return 0;
|
|
|
|
return new AmUnixCtrlInterface();
|
|
}
|
|
|
|
int AmCtrlInterface::getLine(string& line)
|
|
{
|
|
int err = get_line(buffer,CTRL_MSGBUF_SIZE);
|
|
if(err != -1)
|
|
line = buffer;
|
|
return err;
|
|
}
|
|
|
|
int AmCtrlInterface::getLines(string& lines)
|
|
{
|
|
int err = get_lines(buffer,CTRL_MSGBUF_SIZE);
|
|
if(err != -1)
|
|
lines = buffer;
|
|
return err;
|
|
}
|
|
|
|
int AmCtrlInterface::getParam(string& param)
|
|
{
|
|
return get_param(param,buffer,CTRL_MSGBUF_SIZE);
|
|
}
|
|
|
|
|
|
void AmCtrlInterface::consume()
|
|
{}
|
|
|
|
void AmCtrlInterface::close()
|
|
{
|
|
if((fd != -1) && close_fd){
|
|
::close(fd);
|
|
}
|
|
|
|
fd = -1;
|
|
}
|
|
|
|
int AmFifoCtrlInterface::cacheMsg()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int AmFifoCtrlInterface::get_line(char* lb, unsigned int lbs)
|
|
{
|
|
return fifo_get_line(fp_fifo,lb,lbs);
|
|
}
|
|
|
|
int AmFifoCtrlInterface::get_lines(char* lb, unsigned int lbs)
|
|
{
|
|
return fifo_get_lines(fp_fifo,lb,lbs);
|
|
}
|
|
|
|
int AmFifoCtrlInterface::get_param(string& p, char* lb, unsigned int lbs)
|
|
{
|
|
return fifo_get_param(fp_fifo,p,lb,lbs);
|
|
}
|
|
|
|
|
|
AmFifoCtrlInterface::AmFifoCtrlInterface()
|
|
: AmCtrlInterface(), fp_fifo(NULL)
|
|
{
|
|
}
|
|
|
|
AmFifoCtrlInterface::~AmFifoCtrlInterface()
|
|
{
|
|
close();
|
|
}
|
|
|
|
int AmFifoCtrlInterface::createFifo(const string& addr)
|
|
{
|
|
const char* fifo_name = addr.c_str();
|
|
|
|
if( (mkfifo(fifo_name,FIFO_PERM)<0) && (errno!=EEXIST) ) {
|
|
ERROR("while creating fifo `%s': %s \n",fifo_name,strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int AmFifoCtrlInterface::init(const string& addr)
|
|
{
|
|
const char* fifo_name = addr.c_str();
|
|
|
|
if( (mkfifo(fifo_name,FIFO_PERM)<0) && (errno!=EEXIST) ) {
|
|
ERROR("while creating fifo `%s': %s \n",fifo_name,strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
if( !(fd = ::open(fifo_name, O_RDONLY)) ) {
|
|
ERROR("while opening fifo `%s': %s\n",fifo_name,strerror(errno));
|
|
return -1;
|
|
}
|
|
close_fd = true;
|
|
|
|
if(!(fp_fifo = fdopen(fd,"r"))){
|
|
ERROR("while opening fifo `%s' (fdopen): %s\n",fifo_name,strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
filename = addr;
|
|
close_fd = false;
|
|
return 0;
|
|
}
|
|
|
|
int AmFifoCtrlInterface::sendto(const string& addr,const char* buf,unsigned int len)
|
|
{
|
|
return write_to_fifo(addr,buf,len);
|
|
}
|
|
|
|
void AmFifoCtrlInterface::close()
|
|
{
|
|
if((fp_fifo != NULL) && fp_fifo){
|
|
fclose(fp_fifo);
|
|
fp_fifo = NULL;
|
|
AmCtrlInterface::close();
|
|
::unlink(filename.c_str());
|
|
}
|
|
}
|
|
|
|
void AmFifoCtrlInterface::consume()
|
|
{
|
|
while( fifo_get_line(fp_fifo,buffer,CTRL_MSGBUF_SIZE) != 0 ) {
|
|
ERROR("consumed from fifo: %s\n",buffer);
|
|
}
|
|
}
|
|
|
|
int AmUnixCtrlInterface::cacheMsg()
|
|
{
|
|
int err_cnt=0;
|
|
|
|
msg_c = NULL;
|
|
while(true){
|
|
|
|
msg_sz = recv(fd,msg_buf,CTRL_MSGBUF_SIZE,MSG_TRUNC|MSG_DONTWAIT);
|
|
if(msg_sz == -1){
|
|
ERROR("recv on unix socket failed: %s\n",strerror(errno));
|
|
if(++err_cnt >= MAX_MSG_ERR){
|
|
ERROR("too many consecutive errors...\n");
|
|
return -1;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if(msg_sz > CTRL_MSGBUF_SIZE){
|
|
ERROR("unix socket message is too big (size=%i;max=%i): discarding\n",
|
|
msg_sz,CTRL_MSGBUF_SIZE);
|
|
return -1;
|
|
}
|
|
|
|
msg_buf[msg_sz-1] = '\0';
|
|
msg_c = msg_buf;
|
|
|
|
DBG("recv-ed: <%s>\n",msg_buf);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int AmUnixCtrlInterface::get_line(char* lb, unsigned int lbs)
|
|
{
|
|
assert(msg_c);
|
|
return msg_get_line(msg_c,lb,lbs);
|
|
}
|
|
|
|
int AmUnixCtrlInterface::get_lines(char* lb, unsigned int lbs)
|
|
{
|
|
assert(msg_c);
|
|
return msg_get_lines(msg_c,lb,lbs);
|
|
}
|
|
|
|
int AmUnixCtrlInterface::get_param(string& p, char* lb, unsigned int lbs)
|
|
{
|
|
assert(msg_c);
|
|
return msg_get_param(msg_c,p,lb,lbs);
|
|
}
|
|
|
|
AmUnixCtrlInterface::AmUnixCtrlInterface()
|
|
: AmCtrlInterface(),msg_c(NULL),msg_sz(0)
|
|
{
|
|
memset(sock_name,0,UNIX_PATH_MAX);
|
|
}
|
|
|
|
AmUnixCtrlInterface::~AmUnixCtrlInterface()
|
|
{
|
|
close();
|
|
}
|
|
|
|
int AmUnixCtrlInterface::init(const string& addr)
|
|
{
|
|
strncpy(sock_name,addr.c_str(),UNIX_PATH_MAX-1);
|
|
|
|
::unlink(sock_name);
|
|
fd = create_unix_socket(sock_name);
|
|
if(fd == -1){
|
|
ERROR("could not open unix socket '%s'\n",sock_name);
|
|
return -1;
|
|
}
|
|
|
|
DBG("AmUnixCtrlInterface::init @ %s\n", sock_name);
|
|
close_fd = true;
|
|
return 0;
|
|
}
|
|
|
|
int AmUnixCtrlInterface::sendto(const string& addr,const char* buf,unsigned int len)
|
|
{
|
|
return write_to_socket(fd,addr.c_str(),buf,len);
|
|
}
|
|
|
|
void AmUnixCtrlInterface::close()
|
|
{
|
|
AmCtrlInterface::close();
|
|
|
|
if(sock_name[0] != '\0')
|
|
::unlink(sock_name);
|
|
}
|
|
|
|
/**
|
|
* Return:
|
|
* -1 if error.
|
|
* 0 if timeout.
|
|
* 1 if there some datas ready.
|
|
*/
|
|
int AmCtrlInterface::wait4data(int timeout)
|
|
{
|
|
struct pollfd pfd = { fd, POLLIN, 0 };
|
|
|
|
int ret = poll(&pfd,1,timeout);
|
|
if(ret < 0){
|
|
ERROR("poll: %s\n",strerror(errno));
|
|
return -1;
|
|
}
|
|
else if(ret == 0){
|
|
WARN("poll timed out\n");
|
|
return -1;
|
|
}
|
|
|
|
if(pfd.revents & POLLIN)
|
|
return 1;
|
|
else {
|
|
ERROR("poll: revents & POLLIN == 0\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|