#include "sockutil.h" #include "sip-uac.h" #include "sip-uas.h" #include "sip-message.h" #include "sip-transport.h" #include "sip-timer.h" #include "port/ip-route.h" #include "http-parser.h" #include "http-header-auth.h" #include "uri-parse.h" #include "cstringext.h" #include "base64.h" #include "sdp.h" #include "md5.h" #include #define NAME "34020000001320000001" #define DOMAIN "192.168.154.1" struct sip_uas_test_t { socket_t udp; socklen_t addrlen; struct sockaddr_storage addr; http_parser_t* parser; struct sip_agent_t* sip; }; static int sip_uas_transport_send(void* param, const struct cstring_t* /*protocol*/, const struct cstring_t* /*url*/, const struct cstring_t* /*received*/, int /*rport*/, const void* data, int bytes) { struct sip_uas_test_t *test = (struct sip_uas_test_t *)param; //char p1[1024]; //char p2[1024]; printf("%.*s\n\n", (int)bytes, (const char*)data); int r = socket_sendto(test->udp, data, bytes, 0, (struct sockaddr*)&test->addr, test->addrlen); return r == bytes ? 0 : -1; } static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session) { const char* ack = "v=0\n" "o=34020000001320000001 0 0 IN IP4 192.168.128.1\n" "s=Play\n" "c=IN IP4 192.168.128.1\n" "t=0 0\n" "m=video 20120 RTP/AVP 96 98 97\n" "a=sendonly\n" "a=rtpmap:96 PS/90000\n" "a=rtpmap:98 H264/90000\n" "a=rtpmap:97 MPEG4/90000\n" "y=0100000001\n" "f=v/2/4///a///\n"; const cstring_t* h = sip_message_get_header_by_name(req, "Content-Type"); if (0 == cstrcasecmp(h, "Application/SDP")) { sdp_t* sdp = sdp_parse((const char*)data, bytes); sip_uas_add_header(t, "Content-Type", "application/sdp"); sip_uas_add_header(t, "Contact", "sip:34020000001320000001@192.168.154.1"); assert(0 == sip_uas_reply(t, 200, ack, strlen(ack), param)); sdp_destroy(sdp); *session = t; return 0; } else { assert(0); *session = t; return 0; } } /// @param[in] code 0-ok, other-sip status code /// @return 0-ok, other-error static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes) { return 0; } /// on terminating a session(dialog) static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session) { return 0; } /// cancel a transaction(should be an invite transaction) static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session) { return 0; } /// @param[in] expires in seconds static int sip_uas_onregister(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const char* user, const char* location, int expires) { return 0; } static void sip_uas_loop(struct sip_uas_test_t *test) { u_short port; char received[SOCKET_ADDRLEN]; uint8_t buffer[2 * 1024]; do { memset(buffer, 0, sizeof(buffer)); test->addrlen = sizeof(test->addr); int r = socket_recvfrom(test->udp, buffer, sizeof(buffer), 0, (struct sockaddr*)&test->addr, &test->addrlen); socket_addr_to((struct sockaddr*)&test->addr, test->addrlen, received, &port); printf("\n[%s:%hu] %s\n", received, port, buffer); size_t n = r; if (0 == http_parser_input(test->parser, buffer, &n)) { struct sip_message_t* request = sip_message_create(SIP_MESSAGE_REQUEST); r = sip_message_load(request, test->parser); sip_agent_set_rport(request, received, port); assert(0 == sip_agent_input(test->sip, request, test)); sip_message_destroy(request); http_parser_clear(test->parser); } } while (1); } void sip_uas_test(void) { sip_timer_init(); struct sip_uas_handler_t handler; handler.onregister = sip_uas_onregister; handler.oninvite = sip_uas_oninvite; handler.onack = sip_uas_onack; handler.onbye = sip_uas_onbye; handler.oncancel = sip_uas_oncancel; handler.send = sip_uas_transport_send; struct sip_uas_test_t test; test.udp = socket_udp(); test.sip = sip_agent_create(&handler); test.parser = http_parser_create(HTTP_PARSER_REQUEST, NULL, NULL); socket_bind_any(test.udp, SIP_PORT); sip_uas_loop(&test); sip_agent_destroy(test.sip); socket_close(test.udp); http_parser_destroy(test.parser); sip_timer_cleanup(); }