/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * */ /**@@internal * @file test_nua.h * @brief High-level tester framework for Sofia SIP User Agent Engine * * @author Pekka Pessi * @author Martti Mela * * @date Created: Wed Aug 17 12:12:12 EEST 2005 ppessi */ #ifndef TEST_NUA_H #define TEST_NUA_H struct context; #define NUA_MAGIC_T struct context struct call; #define NUA_HMAGIC_T struct call #include "sofia-sip/nua.h" #include "sofia-sip/sip_status.h" #include #include #include #include #include #include #include #if __APPLE_CC__ #include #endif #include "test_proxy.h" #include "test_nat.h" #include #include #include #include #include #include extern char const name[]; extern int print_headings; extern int tstflags; #define TSTFLAGS tstflags #include #define TEST_E(a, b) TEST_S(nua_event_name(a), nua_event_name(b)) #define NONE ((void*)-1) struct endpoint; typedef int condition_function(nua_event_t event, int status, char const *phrase, nua_t *nua, struct context *ctx, struct endpoint *ep, nua_handle_t *nh, struct call *call, sip_t const *sip, tagi_t tags[]); typedef void printer_function(nua_event_t event, char const *operation, int status, char const *phrase, nua_t *nua, struct context *ctx, struct endpoint *ep, nua_handle_t *nh, struct call *call, sip_t const *sip, tagi_t tags[]); struct proxy_transaction; struct registration_entry; enum { event_is_extra, event_is_normal, event_is_special }; struct eventlist { nua_event_t kind; struct event *head, **tail; }; struct event { struct event *next, **prev; struct call *call; nua_saved_event_t saved_event[1]; nua_event_data_t const *data; }; struct context { su_home_t home[1]; su_root_t *root; int threading, proxy_tests, expensive, quit_on_single_failure, osx_runloop; int print_tags; url_t *external_proxy; int proxy_logging; struct endpoint { char name[4]; struct context *ctx; /* Backpointer */ int logging; int print_tags; int running; struct domain *domain; condition_function *next_condition; nua_event_t next_event, last_event; nua_t *nua; sip_contact_t *contact; sip_from_t *to; sip_allow_t *allow; char const *appl_method; sip_supported_t *supported; printer_function *printer; char const *instance; /* Per-call stuff */ struct call { struct call *next; nua_handle_t *nh; char const *sdp; struct eventlist *events; } call[1], reg[1]; int (*is_special)(nua_event_t e); /* Normal events are saved here */ struct eventlist events[1]; /* Special events are saved here */ struct eventlist specials[1]; /* State flags for complex scenarios */ struct { unsigned n; unsigned bit0:1, bit1:1, bit2:1, bit3:1; unsigned bit4:1, bit5:1, bit6:1, bit7:1; unsigned :0; } flags; /* Accross-run state information */ struct { unsigned n; } state; } a, b, c; struct proxy *p; sip_route_t const *lr; struct nat *nat; }; #define RETURN_ON_SINGLE_FAILURE(retval) \ do { \ fflush(stdout); \ if (retval && ctx->quit_on_single_failure) { return retval; } \ } while(0) int save_event_in_list(struct context *, nua_event_t nevent, struct endpoint *, struct call *); void free_events_in_list(struct context *, struct eventlist *); void free_event_in_list(struct context *ctx, struct eventlist *list, struct event *e); struct event *event_by_type(struct event *e, nua_event_t); size_t count_events(struct event const *e); #define CONDITION_PARAMS \ nua_event_t event, \ int status, char const *phrase, \ nua_t *nua, struct context *ctx, \ struct endpoint *ep, \ nua_handle_t *nh, struct call *call, \ sip_t const *sip, \ tagi_t tags[] int save_events(CONDITION_PARAMS); int until_final_response(CONDITION_PARAMS); int save_until_final_response(CONDITION_PARAMS); int save_until_received(CONDITION_PARAMS); int save_until_special(CONDITION_PARAMS); int until_terminated(CONDITION_PARAMS); int until_ready(CONDITION_PARAMS); int accept_call(CONDITION_PARAMS); int cancel_when_ringing(CONDITION_PARAMS); int accept_notify(CONDITION_PARAMS); void a_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, struct context *ctx, nua_handle_t *nh, struct call *call, sip_t const *sip, tagi_t tags[]); void b_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, struct context *ctx, nua_handle_t *nh, struct call *call, sip_t const *sip, tagi_t tags[]); void c_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, struct context *ctx, nua_handle_t *nh, struct call *call, sip_t const *sip, tagi_t tags[]); void run_abc_until(struct context *ctx, nua_event_t a_event, condition_function *a_condition, nua_event_t b_event, condition_function *b_condition, nua_event_t c_event, condition_function *c_condition); void run_ab_until(struct context *ctx, nua_event_t a_event, condition_function *a_condition, nua_event_t b_event, condition_function *b_condition); void run_bc_until(struct context *ctx, nua_event_t b_event, condition_function *b_condition, nua_event_t c_event, condition_function *c_condition); int run_a_until(struct context *, nua_event_t, condition_function *); int run_b_until(struct context *, nua_event_t, condition_function *); int run_c_until(struct context *, nua_event_t, condition_function *); typedef int operation_f(struct endpoint *ep, struct call *call, nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...); operation_f INVITE, ACK, BYE, CANCEL, AUTHENTICATE, UPDATE, INFO, PRACK, REFER, MESSAGE, METHOD, OPTIONS, PUBLISH, UNPUBLISH, REGISTER, UNREGISTER, SUBSCRIBE, UNSUBSCRIBE, NOTIFY, NOTIFIER, TERMINATE, AUTHORIZE; int RESPOND(struct endpoint *ep, struct call *call, nua_handle_t *nh, int status, char const *phrase, tag_type_t tag, tag_value_t value, ...); int DESTROY(struct endpoint *ep, struct call *call, nua_handle_t *nh); struct call *check_handle(struct endpoint *ep, struct call *call, nua_handle_t *nh, int status, char const *phrase); int is_special(nua_event_t e); int callstate(tagi_t const *tags); int is_offer_sent(tagi_t const *tags); int is_answer_sent(tagi_t const *tags); int is_offer_recv(tagi_t const *tags); int is_answer_recv(tagi_t const *tags); int is_offer_answer_done(tagi_t const *tags); int audio_activity(tagi_t const *tags); int video_activity(tagi_t const *tags); void print_event(nua_event_t event, char const *operation, int status, char const *phrase, nua_t *nua, struct context *ctx, struct endpoint *ep, nua_handle_t *nh, struct call *call, sip_t const *sip, tagi_t tags[]); su_inline void eventlist_init(struct eventlist *list) { list->tail = &list->head; } su_inline void call_init(struct call *call) { } void endpoint_init(struct context *ctx, struct endpoint *e, char id); int test_nua_init(struct context *ctx, int start_proxy, url_t const *o_proxy, int start_nat, tag_type_t tag, tag_value_t value, ...); int test_deinit(struct context *ctx); int test_nua_api_errors(struct context *ctx); int test_nua_destroy(struct context *ctx); int test_stack_errors(struct context *ctx); int test_tag_filter(void); int test_nua_params(struct context *ctx); int test_register(struct context *ctx); int test_connectivity(struct context *ctx); int test_nat_timeout(struct context *ctx); int test_unregister(struct context *ctx); int test_basic_call(struct context *ctx); int test_offer_answer(struct context *ctx); int test_rejects(struct context *ctx); int test_mime_negotiation(struct context *ctx); int test_call_timeouts(struct context *ctx); int test_reject_401_aka(struct context *ctx); int test_call_cancel(struct context *ctx); int test_call_destroy(struct context *ctx); int test_early_bye(struct context *ctx); int test_call_hold(struct context *ctx); int test_reinvites(struct context *ctx); int test_session_timer(struct context *ctx); int test_refer(struct context *ctx); int test_100rel(struct context *ctx); int test_simple(struct context *ctx); int test_events(struct context *ctx); int test_extension(struct context *ctx); #endif