comparison test-voice/uac.c @ 0:35c0d9f03c0a

beginning with sipout-test-voice, a copy of sip-manual-out from themwi-system-sw
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 03 Mar 2024 23:20:19 -0800
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:35c0d9f03c0a
1 /*
2 * Here we implement processing of SIP responses to the requests we sent out.
3 */
4
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <strings.h>
13 #include "../libsip/parse.h"
14 #include "../libsip/resp_ident.h"
15 #include "../libsip/out_msg.h"
16
17 #define MAX_TO_TAG 63
18
19 extern char *get_single_header();
20 extern char *extract_to_tag();
21
22 extern struct in_addr sip_bind_ip;
23 extern unsigned sip_bind_port;
24 extern char call_id[], from_uri[], to_uri[];
25 extern unsigned max_forwards;
26
27 char to_tag[MAX_TO_TAG+1];
28
29 add_req_boilerplate(msg, cseq, add_to_tag)
30 struct sip_msg_out *msg;
31 char *cseq;
32 {
33 char strbuf[256];
34 int rc;
35
36 sprintf(strbuf, "SIP/2.0/UDP %s:%u",
37 inet_ntoa(sip_bind_ip), sip_bind_port);
38 rc = out_msg_add_header(msg, "Via", strbuf);
39 if (rc < 0)
40 return rc;
41 rc = out_msg_add_header(msg, "From", from_uri);
42 if (rc < 0)
43 return rc;
44 if (add_to_tag && to_tag[0]) {
45 sprintf(strbuf, "<%s>;tag=%s", to_uri, to_tag);
46 rc = out_msg_add_header(msg, "To", strbuf);
47 } else
48 rc = out_msg_add_header(msg, "To", to_uri);
49 if (rc < 0)
50 return rc;
51 rc = out_msg_add_header(msg, "Call-ID", call_id);
52 if (rc < 0)
53 return rc;
54 rc = out_msg_add_header(msg, "CSeq", cseq);
55 if (rc < 0)
56 return rc;
57 sprintf(strbuf, "%u", max_forwards);
58 return out_msg_add_header(msg, "Max-Forwards", strbuf);
59 }
60
61 add_contact_header(msg)
62 struct sip_msg_out *msg;
63 {
64 char strbuf[80];
65
66 sprintf(strbuf, "<sip:%s:%u;transport=udp>",
67 inet_ntoa(sip_bind_ip), sip_bind_port);
68 return out_msg_add_header(msg, "Contact", strbuf);
69 }
70
71 static void
72 send_ack(sin)
73 struct sockaddr_in *sin;
74 {
75 struct sip_msg_out msg;
76 int rc;
77
78 rc = start_request_out_msg(&msg, "ACK", to_uri);
79 if (rc < 0) {
80 msg_size_err: fprintf(stderr, "composing ACK message: size error\n");
81 return;
82 }
83 rc = add_req_boilerplate(&msg, "1 ACK", 1);
84 if (rc < 0)
85 goto msg_size_err;
86 out_msg_finish(&msg);
87 sip_tx_packet(&msg, sin);
88 }
89
90 static void
91 handle_invite_response(msg, sin)
92 struct sip_pkt_rx *msg;
93 struct sockaddr_in *sin;
94 {
95 char *tag;
96
97 printf("Response to INVITE: %s\n", msg->status_str);
98 tag = extract_to_tag(msg, to_uri);
99 if (tag) {
100 printf("To tag: %s\n", tag);
101 if (strlen(tag) <= MAX_TO_TAG)
102 strcpy(to_tag, tag);
103 else
104 printf("To tag exceeds length limit!\n");
105 }
106 extract_resp_sdp(msg);
107 if (msg->status_code >= 200) {
108 printf("Sending ACK\n");
109 send_ack(sin);
110 if (msg->status_code <= 299)
111 invite_200_rtpout();
112 }
113 }
114
115 void
116 process_sip_response(msg, sin)
117 struct sip_pkt_rx *msg;
118 struct sockaddr_in *sin;
119 {
120 struct sip_resp_ident rid;
121 int rc;
122
123 rc = sip_resp_extract_ident(msg, &rid);
124 if (rc < 0) {
125 printf("SIP %03u response: bad or missing %s header\n",
126 msg->status_code, rid.error_field);
127 return;
128 }
129 if (strcmp(rid.call_id, call_id)) {
130 printf("Got SIP response with wrong Call-ID\n");
131 return;
132 }
133 if (rid.cseq_num == 1 && !strcmp(rid.cseq_method, "INVITE"))
134 handle_invite_response(msg, sin);
135 else if (rid.cseq_num == 1 && !strcmp(rid.cseq_method, "CANCEL"))
136 printf("Response to CANCEL: %s\n", msg->status_str);
137 else if (rid.cseq_num == 2 && !strcmp(rid.cseq_method, "BYE"))
138 printf("Response to BYE: %s\n", msg->status_str);
139 else
140 printf("Got SIP resp for our Call-ID with unknown CSeq %u %s\n",
141 rid.cseq_num, rid.cseq_method);
142 }