Example #1
0
//======================================================================================================================
// Send message through the socket, return true if successful, false o/w
//======================================================================================================================
bool SipConnection::send_message(SipMessage &message)
{
    if(pfd.fd == -1)
    {
        connect();
    }

    time_t start_time = time(nullptr);
    int timeout = 3;
    
    while(time(nullptr) <= start_time + timeout)
    {
        try_poll();
        
        if(pfd.revents & POLLOUT)
        {
            long bytes_to_write;
            message.write_to_buffer(buf, bytes_to_write);
            long bytes_writen = ::write(pfd.fd, buf, bytes_to_write);

            if(bytes_writen != bytes_to_write)
            {
                throw string("write() error");
            }
            
            message.print();
            
            return true;
        }
        
        usleep(1000);
    }
    
    return false;
}
Example #2
0
value ml_select(value fd_list, value timeout)
{
#if defined(HAVE_POLL) && defined(HAVE_SYS_POLL_H) && !defined(__MINGW32__)
    if (use_poll) 
      return try_poll(fd_list, timeout);
    else
      return try_select(fd_list, timeout);
#else
    return try_select(fd_list, timeout);
#endif
}
Example #3
0
//======================================================================================================================
// If optional is false return a message regardless of the kind.
// If optional is true return a message only if it matches the given kind.
// If reconnect is false, don't try to reconnect if the connection is closed.
//======================================================================================================================
SipMessage* SipConnection::get_message(string kind, bool optional, int timeout, bool should_reconnect)
{
    if(pfd.fd == -1)
    {
        if(should_reconnect)
        {
            connect();
        }
        else
        {
            return nullptr;
        }
    }
        
    time_t start_time = time(nullptr);
    
    long old_size = msg_queue.size();
    
    while(msg_queue.empty() && time(nullptr) <= start_time + timeout)
    {
        try_poll(); // Check that there are no errors on the socket and update the pfd.revents field
        
        long num_bytes = 0;
        
        if(pfd.revents & POLLIN) // Socket is ready
        {
            num_bytes = ::read(pfd.fd, buf, CONNECTION_BUFFER_SIZE);
            
            if(num_bytes < 0)
            {
                throw string("read() error");
            }
            else if(num_bytes == 0) // Other side issued a close of the TCP connection
            {
                if(should_reconnect)
                {
                    // This might be the close of the connection from a previous test, because get_message() is called
                    // on demand only. So reconnect and continue to try and receive a message.
                    reconnect();
                    continue;
                }
                else
                {
                    return nullptr;
                }
            }
            else // Successful read
            {
                buf[num_bytes] = '\0'; // Make buf a null-terminated string to enable printing etc.
                
                // The buffer might contain more than one sip message, extract all of them into the messages queue
                for(long offset = 0; num_bytes > 0; num_bytes -= offset)
                {
                    msg_queue.push_back(new SipMessage(buf + offset, offset, num_bytes));
                }

                break;
            }
        }
        
        usleep(1000);
    }
    
    if(!msg_queue.empty())
    {
        for(long i = old_size; i < msg_queue.size(); ++i)
        {
            msg_queue[i]->print();
        }

        SipMessage* front = msg_queue.front();

        if(!optional || front->get_kind() == kind)
        {
            msg_queue.pop_front();
            return front;
        }
    }
    
    return nullptr;

} // get_message()