FreeCalypso > hg > sipout-test-utils
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 } |