Esempio n. 1
0
int
call_attr_compare(sip_call_t *one, sip_call_t *two, enum sip_attr_id id)
{
    char onevalue[256], twovalue[256];
    int oneintvalue, twointvalue;
    int comparetype; /* TODO 0 = string compare, 1 = int comprare */

    switch (id) {
        case SIP_ATTR_CALLINDEX:
            oneintvalue = one->index;
            twointvalue = two->index;
            comparetype = 1;
            break;
        case SIP_ATTR_MSGCNT:
            oneintvalue = call_msg_count(one);
            twointvalue = call_msg_count(two);
            comparetype = 1;
            break;
        default:
            // Get attribute values
            memset(onevalue, 0, sizeof(onevalue));
            memset(twovalue, 0, sizeof(twovalue));
            call_get_attribute(one, id, onevalue);
            call_get_attribute(two, id, twovalue);
            comparetype = 0;
            break;
    }

    switch (comparetype) {
        case 0:
            if (strlen(twovalue) == 0 && strlen(onevalue) == 0)
                return 0;
            if (strlen(twovalue) == 0)
                return 1;
            if (strlen(onevalue) == 0)
                return -1;
            return strcmp(onevalue, twovalue);
        case 1:
            if (oneintvalue == twointvalue) return 0;
            if (oneintvalue > twointvalue) return 1;
            if (oneintvalue < twointvalue) return -1;
            /* no break */
        default:
            return 0;
    }
}
Esempio n. 2
0
const char *
call_get_attribute(sip_call_t *call, enum sip_attr_id id)
{
    char value[80];
    if (id == SIP_ATTR_MSGCNT) {
        // FIXME REALLY
        sprintf(value, "%d", call_msg_count(call));
        return strdup(value);
    }
    if (id == SIP_ATTR_STARTING) {
        return msg_get_attribute(call_get_next_msg(call, NULL), SIP_ATTR_METHOD);
    }
    return msg_get_attribute(call_get_next_msg(call, NULL), id);
}
Esempio n. 3
0
sip_msg_t *
sip_check_packet(packet_t *packet)
{
    sip_msg_t *msg;
    sip_call_t *call;
    char callid[1024], xcallid[1024];
    address_t src, dst;
    u_char payload[MAX_SIP_PAYLOAD];
    bool newcall = false;

    // Max SIP payload allowed
    if (packet->payload_len > MAX_SIP_PAYLOAD)
        return NULL;

    // Get Addresses from packet
    src = packet->src;
    dst = packet->dst;

    // Initialize local variables
    memset(callid, 0, sizeof(callid));
    memset(xcallid, 0, sizeof(xcallid));

    // Get payload from packet(s)
    memset(payload, 0, MAX_SIP_PAYLOAD);
    memcpy(payload, packet_payload(packet), packet_payloadlen(packet));

    // Get the Call-ID of this message
    if (!sip_get_callid((const char*) payload, callid))
        return NULL;

    // Create a new message from this data
    if (!(msg = msg_create((const char*) payload)))
        return NULL;

    // Get Method and request for the following checks
    // There is no need to parse all payload at this point
    // If no response or request code is found, this is not a SIP message
    if (!sip_get_msg_reqresp(msg, payload)) {
        // Deallocate message memory
        msg_destroy(msg);
        return NULL;
    }

    // Find the call for this msg
    if (!(call = sip_find_by_callid(callid))) {

        // Check if payload matches expression
        if (!sip_check_match_expression((const char*) payload))
            goto skip_message;

        // User requested only INVITE starting dialogs
        if (calls.only_calls && msg->reqresp != SIP_METHOD_INVITE)
            goto skip_message;

        // Only create a new call if the first msg
        // is a request message in the following gorup
        if (calls.ignore_incomplete && msg->reqresp > SIP_METHOD_MESSAGE)
            goto skip_message;

        // Get the Call-ID of this message
        sip_get_xcallid((const char*) payload, xcallid);

        // Rotate call list if limit has been reached
        if (calls.limit == sip_calls_count())
            sip_calls_rotate();

        // Create the call if not found
        if (!(call = call_create(callid, xcallid)))
            goto skip_message;

        // Add this Call-Id to hash table
        htable_insert(calls.callids, call->callid, call);

        // Set call index
        call->index = ++calls.last_index;

        // Mark this as a new call
        newcall = true;
    }

    // At this point we know we're handling an interesting SIP Packet
    msg->packet = packet;

    // Always parse first call message
    if (call_msg_count(call) == 0) {
        // Parse SIP payload
        sip_parse_msg_payload(msg, payload);
        // If this call has X-Call-Id, append it to the parent call
        if (strlen(call->xcallid)) {
            call_add_xcall(sip_find_by_callid(call->xcallid), call);
        }
    }

    // Add the message to the call
    call_add_message(call, msg);

    if (call_is_invite(call)) {
        // Parse media data
        sip_parse_msg_media(msg, payload);
        // Update Call State
        call_update_state(call, msg);
        // Check if this call should be in active call list
        if (call_is_active(call)) {
            if (sip_call_is_active(call)) {
                vector_append(calls.active, call);
            }
        } else {
            if (sip_call_is_active(call)) {
                vector_remove(calls.active, call);
            }
        }
    }

    if (newcall) {
        // Append this call to the call list
        vector_append(calls.list, call);
    }

    // Mark the list as changed
    calls.changed = true;

    // Return the loaded message
    return msg;

skip_message:
    // Deallocate message memory
    msg_destroy(msg);
    return NULL;

}
Esempio n. 4
0
void
call_list_draw_list(PANEL *panel)
{
    WINDOW *win;
    int height, width, cline = 0;
    struct sip_call *call;
    int i, collen;
    char coltext[256];
    int colid;
    int colpos;
    int color;

    // Get panel info
    call_list_info_t *info = call_list_info(panel);

    // Get window of call list panel
    win = info->list_win;
    getmaxyx(win, height, width);

    // If autoscroll is enabled, select the last dialog
    if (info->autoscroll) {
        call_list_handle_key(panel, key_action_key(ACTION_END));
    }

    // If no active call, use the fist one (if exists)
    if (info->first_call == -1 && vector_iterator_count(&info->calls)) {
        vector_iterator_reset(&info->calls);
        call = vector_iterator_next(&info->calls);
        info->cur_call = info->first_call = vector_index(vector_iterator_vector(&info->calls), call);
        info->cur_line = info->first_line = 1;
    }

    // Clear call list before redrawing
    werase(win);

    // Set the iterator position to the first call
    vector_iterator_set_current(&info->calls, info->first_call - 1 );

    // Fill the call list
    while ((call = vector_iterator_next(&info->calls))) {
        // Stop if we have reached the bottom of the list
        if (cline == height)
            break;

        // We only print calls with messages (In fact, all call should have msgs)
        if (!call_msg_count(call))
            continue;

        // Show bold selected rows
        if (call_group_exists(info->group, call))
            wattron(win, A_BOLD | COLOR_PAIR(CP_DEFAULT));

        // Highlight active call
        if (call->index == info->cur_call + 1) {
            wattron(win, COLOR_PAIR(CP_WHITE_ON_BLUE));
            // Reverse colors on monochrome terminals
            if (!has_colors())
                wattron(win, A_REVERSE);
        }
        // Set current line background
        clear_line(win, cline);
        // Set current line selection box
        mvwprintw(win, cline, 2, call_group_exists(info->group, call) ? "[*]" : "[ ]");

        // Print requested columns
        colpos = 6;
        for (i = 0; i < info->columncnt; i++) {
            // Get current column id
            colid = info->columns[i].id;
            // Get current column width
            collen = info->columns[i].width;
            // Check if next column fits on window width
            if (colpos + collen >= width)
                break;

            // Initialize column text
            memset(coltext, 0, sizeof(coltext));

            // Get call attribute for current column
            if (!call_get_attribute(call, colid, coltext)) {
                colpos += collen + 1;
                continue;
            }

            // Enable attribute color (if not current one)
            color = 0;
            if (call->index != info->cur_call + 1 && (color = sip_attr_get_color(colid, coltext)) > 0)
                wattron(win, color);

            // Add the column text to the existing columns
            mvwprintw(win, cline, colpos, "%.*s", collen, coltext);
            colpos += collen + 1;

            // Disable attribute color
            if (color > 0)
                wattroff(win, color);
        }
        cline++;

        wattroff(win, COLOR_PAIR(CP_DEFAULT));
        wattroff(win, COLOR_PAIR(CP_DEF_ON_BLUE));
        wattroff(win, A_BOLD | A_REVERSE);
    }

    // Draw scrollbar to the right
    draw_vscrollbar(win, info->first_line, info->dispcallcnt, 1);
    wnoutrefresh(info->list_win);

}