blob: 25b2a2ea72fed519036fdbc50dd61e540509ad0b [file] [log] [blame]
Adrien Béraud612b55b2023-05-29 10:42:04 -04001/*
2 * Copyright (C) 2004-2023 Savoir-faire Linux Inc.
3 *
Adrien Béraudcb753622023-07-17 22:32:49 -04004 * This program is free software: you can redistribute it and/or modify
Adrien Béraud612b55b2023-05-29 10:42:04 -04005 * it under the terms of the GNU General Public License as published by
Adrien Béraudcb753622023-07-17 22:32:49 -04006 * the Free Software Foundation, either version 3 of the License, or
Adrien Béraud612b55b2023-05-29 10:42:04 -04007 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Adrien Béraudcb753622023-07-17 22:32:49 -040011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Adrien Béraud612b55b2023-05-29 10:42:04 -040012 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
Adrien Béraudcb753622023-07-17 22:32:49 -040015 * along with this program. If not, see <https://www.gnu.org/licenses/>.
Adrien Béraud612b55b2023-05-29 10:42:04 -040016 */
Adrien Béraud612b55b2023-05-29 10:42:04 -040017#pragma once
18
19#include "ip_utils.h"
20
21#include <utility>
22#include <string>
23#include <vector>
24#include <cstring> // strcmp
25
26#include <pjsip/sip_msg.h>
27#include <pjlib.h>
28#include <pj/pool.h>
29#include <pjsip/sip_endpoint.h>
30#include <pjsip/sip_dialog.h>
31
Adrien Béraud1ae60aa2023-07-07 09:55:09 -040032namespace dhtnet {
Adrien Béraud612b55b2023-05-29 10:42:04 -040033namespace sip_utils {
34
35using namespace std::literals;
36
37// SIP methods. Only list methods that need to be explicitly
38// handled
39
40namespace SIP_METHODS {
41constexpr std::string_view MESSAGE = "MESSAGE"sv;
42constexpr std::string_view INFO = "INFO"sv;
43constexpr std::string_view OPTIONS = "OPTIONS"sv;
44constexpr std::string_view PUBLISH = "PUBLISH"sv;
45constexpr std::string_view REFER = "REFER"sv;
46constexpr std::string_view NOTIFY = "NOTIFY"sv;
47} // namespace SIP_METHODS
48
49static constexpr int DEFAULT_SIP_PORT {5060};
50static constexpr int DEFAULT_SIP_TLS_PORT {5061};
51static constexpr int DEFAULT_AUTO_SELECT_PORT {0};
52
53/// PjsipErrorCategory - a PJSIP error category for std::error_code
54class PjsipErrorCategory final : public std::error_category
55{
56public:
57 const char* name() const noexcept override { return "pjsip"; }
58 std::string message(int condition) const override;
59};
60
61/// PJSIP related exception
62/// Based on std::system_error with code() returning std::error_code with PjsipErrorCategory category
63class PjsipFailure : public std::system_error
64{
65private:
66 static constexpr const char* what_ = "PJSIP call failed";
67
68public:
69 PjsipFailure()
70 : std::system_error(std::error_code(PJ_EUNKNOWN, PjsipErrorCategory()), what_)
71 {}
72
73 explicit PjsipFailure(pj_status_t status)
74 : std::system_error(std::error_code(status, PjsipErrorCategory()), what_)
75 {}
76};
77
78
79/**
80 * Helper function to parser header from incoming sip messages
81 * @return Header from SIP message
82 */
83/*std::string fetchHeaderValue(pjsip_msg* msg, const std::string& field);
84
85pjsip_route_hdr* createRouteSet(const std::string& route, pj_pool_t* hdr_pool);
86
87std::string_view stripSipUriPrefix(std::string_view sipUri);
88
89std::string parseDisplayName(const pjsip_name_addr* sip_name_addr);
90std::string parseDisplayName(const pjsip_from_hdr* header);
91std::string parseDisplayName(const pjsip_contact_hdr* header);
92
93std::string_view getHostFromUri(std::string_view sipUri);
94
95void addContactHeader(const std::string& contact, pjsip_tx_data* tdata);
96void addUserAgentHeader(const std::string& userAgent, pjsip_tx_data* tdata);
97std::string_view getPeerUserAgent(const pjsip_rx_data* rdata);
98std::vector<std::string> getPeerAllowMethods(const pjsip_rx_data* rdata);
99void logMessageHeaders(const pjsip_hdr* hdr_list);*/
100
101std::string_view sip_strerror(pj_status_t code);
102
103// Helper function that return a constant pj_str_t from an array of any types
104// that may be statically casted into char pointer.
105// Per convention, the input array is supposed to be null terminated.
106template<typename T, std::size_t N>
107constexpr const pj_str_t
108CONST_PJ_STR(T (&a)[N]) noexcept
109{
110 return {const_cast<char*>(a), N - 1};
111}
112
113inline const pj_str_t
114CONST_PJ_STR(const std::string& str) noexcept
115{
116 return {const_cast<char*>(str.c_str()), (pj_ssize_t) str.size()};
117}
118
119inline constexpr pj_str_t
120CONST_PJ_STR(const std::string_view& str) noexcept
121{
122 return {const_cast<char*>(str.data()), (pj_ssize_t) str.size()};
123}
124
125inline constexpr std::string_view
126as_view(const pj_str_t& str) noexcept
127{
128 return {str.ptr, (size_t) str.slen};
129}
130
131// PJSIP dialog locking in RAII way
132// Usage: declare local variable like this: sip_utils::PJDialogLock lock {dialog};
133// The lock is kept until the local variable is deleted
134class PJDialogLock
135{
136public:
137 explicit PJDialogLock(pjsip_dialog* dialog)
138 : dialog_(dialog)
139 {
140 pjsip_dlg_inc_lock(dialog_);
141 }
142
143 ~PJDialogLock() { pjsip_dlg_dec_lock(dialog_); }
144
145private:
146 PJDialogLock(const PJDialogLock&) = delete;
147 PJDialogLock& operator=(const PJDialogLock&) = delete;
148 pjsip_dialog* dialog_ {nullptr};
149};
150
151// Helper on PJSIP memory pool allocation from endpoint
152// This encapsulate the allocated memory pool inside a unique_ptr
153static inline std::unique_ptr<pj_pool_t, decltype(pj_pool_release)&>
154smart_alloc_pool(pjsip_endpoint* endpt, const char* const name, pj_size_t initial, pj_size_t inc)
155{
156 auto pool = pjsip_endpt_create_pool(endpt, name, initial, inc);
157 if (not pool)
158 throw std::bad_alloc();
159 return std::unique_ptr<pj_pool_t, decltype(pj_pool_release)&>(pool, pj_pool_release);
160}
161
162void sockaddr_to_host_port(pj_pool_t* pool, pjsip_host_port* host_port, const pj_sockaddr* addr);
163
164static constexpr int POOL_TP_INIT {512};
165static constexpr int POOL_TP_INC {512};
166static constexpr int TRANSPORT_INFO_LENGTH {64};
167
168} // namespace sip_utils
169} // namespace jami