Statistics
| Branch: | Revision:

janus-gateway / utils.h @ 887df302

History | View | Annotate | Download (10.1 KB)

1
/*! \file    utils.h
2
 * \author   Lorenzo Miniero <lorenzo@meetecho.com>
3
 * \copyright GNU General Public License v3
4
 * \brief    Utilities and helpers (headers)
5
 * \details  Implementations of a few methods that may be of use here
6
 * and there in the code.
7
 * 
8
 * \ingroup core
9
 * \ref core
10
 */
11
 
12
#ifndef _JANUS_UTILS_H
13
#define _JANUS_UTILS_H
14

    
15
#include <stdint.h>
16
#include <glib.h>
17
#include <netinet/in.h>
18
#include <jansson.h>
19

    
20
/* Use JANUS_JSON_BOOL instead of the non-existing JSON_BOOLEAN */
21
#define JANUS_JSON_BOOL JSON_TRUE
22
#define JANUS_JSON_PARAM_REQUIRED 1
23
#define JANUS_JSON_PARAM_POSITIVE 2
24
#define JANUS_JSON_PARAM_NONEMPTY 4
25

    
26
struct janus_json_parameter {
27
        const gchar *name;
28
        json_type jtype;
29
        unsigned int flags;
30
};
31

    
32
/*! \brief Helper to retrieve the system monotonic time, as Glib's
33
 * g_get_monotonic_time may not be available (only since 2.28)
34
 * @returns The system monotonic time */
35
gint64 janus_get_monotonic_time(void);
36

    
37
/*! \brief Helper to retrieve the system real time, as Glib's
38
 * g_get_real_time may not be available (only since 2.28)
39
 * @returns The system real time */
40
gint64 janus_get_real_time(void);
41

    
42
/*! \brief Helper to replace strings
43
 * @param message The string that contains the text to replace, which may be
44
 * freed if it is too short
45
 * @param old_string The old text to replace
46
 * @param new_string The new text
47
 * @returns A pointer to the updated text string (re-allocated or just updated) */
48
char *janus_string_replace(char *message, const char *old_string, const char *new_string) G_GNUC_WARN_UNUSED_RESULT;
49

    
50
/*! \brief Helper to parse yes/no|true/false configuration values
51
 * @param value The configuration value to parse
52
 * @returns true if the value contains a "yes", "YES", "true", TRUE", "1", false otherwise */
53
gboolean janus_is_true(const char *value);
54

    
55
/*! \brief Helper to compare strings in constant time
56
 * @param str1 The first string to compare
57
 * @param str2 The second string to compare
58
 * @returns true if the strings are the same, false otherwise */
59
gboolean janus_strcmp_const_time(const void *str1, const void *str2);
60

    
61
/** @name Flags helper methods
62
 */
63
///@{
64
/*! \brief Janus flags container */
65
typedef uint32_t janus_flags;
66

    
67
/*! \brief Janus flags reset method
68
 * \param[in] flags The janus_flags instance to reset */
69
void janus_flags_reset(janus_flags *flags);
70

    
71
/*! \brief Janus flags set method
72
 * \param[in] flags The janus_flags instance to update
73
 * \param[in] flag The flag to set */
74
void janus_flags_set(janus_flags *flags, uint32_t flag);
75

    
76
/*! \brief Janus flags clear method
77
 * \param[in] flags The janus_flags instance to update
78
 * \param[in] flag The flag to clear */
79
void janus_flags_clear(janus_flags *flags, uint32_t flag);
80

    
81
/*! \brief Janus flags check method
82
 * \param[in] flags The janus_flags instance to check
83
 * \param[in] flag The flag to check
84
 * \returns true if the flag is set, false otherwise */
85
gboolean janus_flags_is_set(janus_flags *flags, uint32_t flag);
86
///@}
87

    
88
/*! \brief Helper to create a new directory, and recursively create parent directories if needed
89
 * @param dir Path to the new folder to create
90
 * @param mode File permissions for the new directory file
91
 * @returns An integer like the regular mkdir does
92
 * @note A failure may indicate that creating any of the subdirectories failed: some may still have been created */
93
int janus_mkdir(const char *dir, mode_t mode);
94

    
95
/*! \brief Ugly and dirty helper to quickly get the Opus payload type in an SDP
96
 * @param sdp The SDP to parse
97
 * @returns The Opus payload type, if found, -1 otherwise */
98
int janus_get_opus_pt(const char *sdp);
99

    
100
/*! \brief Ugly and dirty helper to quickly get the ISAC 32K payload type in an SDP
101
 * @param sdp The SDP to parse
102
 * @returns The ISAC 32K payload type, if found, -1 otherwise */
103
int janus_get_isac32_pt(const char *sdp);
104

    
105
/*! \brief Ugly and dirty helper to quickly get the ISAC 16K payload type in an SDP
106
 * @param sdp The SDP to parse
107
 * @returns The ISAC 16K payload type, if found, -1 otherwise */
108
int janus_get_isac16_pt(const char *sdp);
109

    
110
/*! \brief Ugly and dirty helper to quickly get the PCMU payload type in an SDP
111
 * @param sdp The SDP to parse
112
 * @returns The PCMU payload type, if found, -1 otherwise */
113
int janus_get_pcmu_pt(const char *sdp);
114

    
115
/*! \brief Ugly and dirty helper to quickly get the PCMU payload type in an SDP
116
 * @param sdp The SDP to parse
117
 * @returns The PCMA payload type, if found, -1 otherwise */
118
int janus_get_pcma_pt(const char *sdp);
119

    
120
/*! \brief Ugly and dirty helper to quickly get the VP8 payload type in an SDP
121
 * @param sdp The SDP to parse
122
 * @returns The VP8 payload type, if found, -1 otherwise */
123
int janus_get_vp8_pt(const char *sdp);
124

    
125
/*! \brief Ugly and dirty helper to quickly get the VP9 payload type in an SDP
126
 * @param sdp The SDP to parse
127
 * @returns The VP9 payload type, if found, -1 otherwise */
128
int janus_get_vp9_pt(const char *sdp);
129

    
130
/*! \brief Ugly and dirty helper to quickly get the H.264 payload type in an SDP
131
 * @param sdp The SDP to parse
132
 * @returns The H.264 payload type, if found, -1 otherwise */
133
int janus_get_h264_pt(const char *sdp);
134

    
135
/*! \brief Check if the given IP address is valid: family is set to the address family if the IP is valid
136
 * @param ip The IP address to check
137
 * @param[in,out] family The address family of the address, set by the method if valid
138
 * @returns true if the address is valid, false otherwise */
139
gboolean janus_is_ip_valid(const char *ip, int *family);
140

    
141
/*! \brief Convert a sockaddr address to an IP string
142
 * \note The resulting string is allocated, which means the caller must free it itself when done
143
 * @param address The sockaddr address to convert
144
 * @returns A string containing the IP address, if successful, NULL otherwise */
145
char *janus_address_to_ip(struct sockaddr *address);
146

    
147
/*! \brief Create and lock a PID file
148
 * @param file Path to the PID file to use
149
 * @returns 0 if successful, a negative integer otherwise */
150
int janus_pidfile_create(const char *file);
151

    
152
/*! \brief Unlock and remove a previously created PID file
153
 * @returns 0 if successful, a negative integer otherwise */
154
int janus_pidfile_remove(void);
155

    
156
/*! \brief Creates a string describing the JSON type and constraint
157
 * @param jtype The JSON type, e.g., JSON_STRING
158
 * @param flags Indicates constraints for the described type
159
 * @param[out] The type description, e.g., "a positive integer"; required size is 19 characters
160
 * @returns 0 if successful, a negative integer otherwise */
161
void janus_get_json_type_name(int jtype, unsigned int flags, char *type_name);
162

    
163
/*! \brief Checks whether the JSON value matches the type and constraint
164
 * @param val The JSON value to be checked
165
 * @param jtype The JSON type, e.g., JSON_STRING
166
 * @param flags Indicates constraints for the described type
167
 * @returns TRUE if the value is valid */
168
gboolean janus_json_is_valid(json_t *val, json_type jtype, unsigned int flags);
169

    
170
/*! \brief Validates the JSON object against the description of its parameters
171
 * @param missing_format printf format to indicate a missing required parameter; needs one %s for the parameter name
172
 * @param invalid_format printf format to indicate an invalid parameter; needs two %s for parameter name and type description from janus_get_json_type_name
173
 * @param obj The JSON object to be validated
174
 * @param params Array of struct janus_json_parameter to describe the parameters; the array has to be a global or stack variable to make sizeof work
175
 * @param[out] error_code int to return error code
176
 * @param[out] error_cause Array of char or NULL to return the error descriptions; the array has to be a global or stack variable to make sizeof work; the required size is the length of the format string plus the length of the longest parameter name plus 19 for the type description
177
 * @param log_error If TRUE, log any error with JANUS_LOG(LOG_ERR)
178
 * @param missing_code The code to be returned in error_code if a parameter is missing
179
 * @param invalid_code The code to be returned in error_code if a parameter is invalid */
180
#define JANUS_VALIDATE_JSON_OBJECT_FORMAT(missing_format, invalid_format, obj, params, error_code, error_cause, log_error, missing_code, invalid_code) \
181
        do { \
182
                error_code = 0; \
183
                unsigned int i; \
184
                for(i = 0; i < sizeof(params) / sizeof(struct janus_json_parameter); i++) { \
185
                        json_t *val = json_object_get(obj, params[i].name); \
186
                        if(!val) { \
187
                                if((params[i].flags & JANUS_JSON_PARAM_REQUIRED) != 0) {        \
188
                                        error_code = (missing_code); \
189
                                        if(log_error) \
190
                                                JANUS_LOG(LOG_ERR, missing_format "\n", params[i].name); \
191
                                        if(error_cause != NULL) \
192
                                                g_snprintf(error_cause, sizeof(error_cause), missing_format, params[i].name); \
193
                                        break; \
194
                                } \
195
                                continue; \
196
                        } \
197
                        if(!janus_json_is_valid(val, params[i].jtype, params[i].flags)) { \
198
                                error_code = (invalid_code); \
199
                                char type_name[20]; \
200
                                janus_get_json_type_name(params[i].jtype, params[i].flags, type_name); \
201
                                if(log_error) \
202
                                        JANUS_LOG(LOG_ERR, invalid_format "\n", params[i].name, type_name); \
203
                                if(error_cause != NULL) \
204
                                        g_snprintf(error_cause, sizeof(error_cause), invalid_format, params[i].name, type_name); \
205
                                break; \
206
                        } \
207
                } \
208
        } while(0)
209

    
210
/*! \brief Validates the JSON object against the description of its parameters
211
 * @param obj The JSON object to be validated
212
 * @param params Array of struct janus_json_parameter to describe the parameters; the array has to be a global or stack variable to make sizeof work
213
 * @param[out] error_code int to return error code
214
 * @param[out] error_cause Array of char or NULL to return the error descriptions; the array has to be a global or stack variable to make sizeof work; the required size is the length of the longest parameter name plus 54 for the format string and type description
215
 * @param log_error If TRUE, log any error with JANUS_LOG(LOG_ERR)
216
 * @param missing_code The code to be returned in error_code if a parameter is missing
217
 * @param invalid_code The code to be returned in error_code if a parameter is invalid */
218
#define JANUS_VALIDATE_JSON_OBJECT(obj, params, error_code, error_cause, log_error, missing_code, invalid_code) \
219
        JANUS_VALIDATE_JSON_OBJECT_FORMAT("Missing mandatory element (%s)", "Invalid element type (%s should be %s)", obj, params, error_code, error_cause, log_error, missing_code, invalid_code)
220

    
221
#endif