|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "CSFLog.h" |
|
6 |
|
7 #include "CC_Common.h" |
|
8 #include "csf_common.h" |
|
9 #ifdef WIN32 |
|
10 #include <windows.h> |
|
11 #else |
|
12 #ifdef LINUX |
|
13 // for platGetIPAddr |
|
14 #include <sys/ioctl.h> |
|
15 #include <sys/types.h> |
|
16 #include <arpa/inet.h> |
|
17 #include <net/if.h> |
|
18 #include <fcntl.h> |
|
19 #endif |
|
20 #endif |
|
21 |
|
22 #include "cpr_string.h" |
|
23 |
|
24 static const char* logTag = "sipcc"; |
|
25 |
|
26 extern "C" |
|
27 { |
|
28 #include "plat_api.h" |
|
29 #include <stdarg.h> |
|
30 |
|
31 |
|
32 void NotifyStateChange (cc_callid_t callid, int32_t state) { |
|
33 //Don't need anything here. |
|
34 //Call state change are notified to us via SIPCC "high level" API |
|
35 } |
|
36 |
|
37 #ifndef OSX |
|
38 /** |
|
39 * platGetFeatureAllowed |
|
40 * |
|
41 * Get whether the feature is allowed |
|
42 * |
|
43 * @param featureId - sis feature id |
|
44 * |
|
45 * @return 1 - allowed, 0 - not allowed |
|
46 * |
|
47 */ |
|
48 int platGetFeatureAllowed(cc_sis_feature_id_e featureId) { |
|
49 return 1; |
|
50 } |
|
51 |
|
52 /** |
|
53 * Set the Status message for failure reasons |
|
54 * @param char *msg |
|
55 * @return void |
|
56 */ |
|
57 void platSetStatusMessage(char *msg) { |
|
58 } |
|
59 |
|
60 /** |
|
61 * Sets the time based on Date header in 200 OK from REGISTER request |
|
62 * @param void |
|
63 * @return void |
|
64 */ |
|
65 void platSetCucmRegTime (void) { |
|
66 } |
|
67 |
|
68 /** |
|
69 * Enable / disable speaker |
|
70 * |
|
71 * @param[in] state - true -> enable speaker, false -> disable speaker |
|
72 * |
|
73 * @return void |
|
74 */ |
|
75 extern "C" void platSetSpeakerMode(cc_boolean state) { |
|
76 } |
|
77 |
|
78 /** |
|
79 * Get the status (on/off) of the audio device |
|
80 * |
|
81 * @param[in] device_type - headset or speaker (see vcm_audio_device_t) |
|
82 * |
|
83 * @return 1 -> On, 0 -> off, ERROR -> unknown (error) |
|
84 */ |
|
85 int platGetAudioDeviceStatus(plat_audio_device_t device_type) { |
|
86 //Tell SIPCC what the current audio path is by return 1 for one of either: headset or speaker. |
|
87 return 1; |
|
88 } |
|
89 |
|
90 /** |
|
91 * Check if the speaker or headset is enabled. |
|
92 * |
|
93 * @return boolean if the speaker or headset is enabled, returns true. |
|
94 */ |
|
95 boolean platGetSpeakerHeadsetMode() { |
|
96 return TRUE; |
|
97 } |
|
98 #endif |
|
99 |
|
100 /** |
|
101 * Provides the local MAC address |
|
102 * |
|
103 * @param *maddr the pointer to the string holding MAC address |
|
104 * in the MAC address format after converting from string format. |
|
105 * @return void |
|
106 */ |
|
107 void platGetMacAddr(char *maddr) { |
|
108 //Strictly speaking the code using this is not treating this as a string. |
|
109 //It's taking the first 6 bytes out of the buffer, and printing these |
|
110 //directly, so it's not enough to just make the first byte '\0' need |
|
111 //to set all of the bytes in range 0-5 equal to '\0'. |
|
112 //Have to assume here that the buffer is big enough. |
|
113 for (int i=0; i<6; i++) |
|
114 { |
|
115 *(maddr+i) = '\0'; |
|
116 } |
|
117 } |
|
118 |
|
119 #ifndef OSX |
|
120 /** |
|
121 * Called by the thread to initialize any thread specific data |
|
122 * once the thread is created. |
|
123 * |
|
124 * @param[in] tname thread name |
|
125 * |
|
126 * @return 0 - SUCCESS |
|
127 * -1 - FAILURE |
|
128 */ |
|
129 int platThreadInit(char * tname) { |
|
130 return 0; |
|
131 } |
|
132 |
|
133 /** |
|
134 * The initial initialization function for any platform related |
|
135 * modules |
|
136 * |
|
137 * |
|
138 * @return 0 - SUCCESS |
|
139 * -1 - FAILURE |
|
140 */ |
|
141 int platInit() { |
|
142 return 0; |
|
143 } |
|
144 |
|
145 /** |
|
146 * The initial initialization function for the debugging/logging |
|
147 * modules |
|
148 * |
|
149 */ |
|
150 void debugInit() { |
|
151 return ; |
|
152 } |
|
153 |
|
154 /** |
|
155 * Add cc control classifier |
|
156 * |
|
157 * Called by SIP stack to specify addresses and ports that will be used for call control |
|
158 * |
|
159 * @param[in] myIPAddr - phone local interface IP Address |
|
160 * @param[in] myPort - phone local interface Port |
|
161 * @param[in] cucm1IPAddr - CUCM 1 IP Address |
|
162 * @param[in] cucm1Port - CUCM 1 Port |
|
163 * @param[in] cucm2IPAddr - CUCM 2 IP Address |
|
164 * @param[in] cucm2Port - CUCM 2 Port |
|
165 * @param[in] cucm3IPAddr - CUCM 3 IP Address |
|
166 * @param[in] cucm3Port - CUCM 3 Port |
|
167 * @param[in] protocol - CC_IPPROTO_UDP or CC_IP_PROTO_TCP |
|
168 * |
|
169 * @note : Needed only if using WiFi. If not using Wifi please provide a stub |
|
170 */ |
|
171 void platAddCallControlClassifiers(unsigned long myIPAddr, unsigned short myPort, |
|
172 unsigned long cucm1IPAddr, unsigned short cucm1Port, |
|
173 unsigned long cucm2IPAddr, unsigned short cucm2Port, |
|
174 unsigned long cucm3IPAddr, unsigned short cucm3Port, |
|
175 unsigned char protocol) { |
|
176 //Needed only if using WiFi. If not using Wifi please provide a stub |
|
177 } |
|
178 |
|
179 /** |
|
180 * Remove cc control classifier. |
|
181 * |
|
182 * Undo platAddCallControlClassifiers |
|
183 */ |
|
184 void platRemoveCallControlClassifiers() { |
|
185 //Needed only if using WiFi. If not using Wifi please provide a stub |
|
186 } |
|
187 |
|
188 /** |
|
189 * Set ip address mode |
|
190 * e.g. |
|
191 * |
|
192 */ |
|
193 cpr_ip_mode_e platGetIpAddressMode() { |
|
194 return CPR_IP_MODE_IPV4; |
|
195 } |
|
196 |
|
197 /** |
|
198 * Tell whether wifi is supported and active |
|
199 * |
|
200 * @return boolean wether WLAN is active or not |
|
201 */ |
|
202 cc_boolean platWlanISActive() { |
|
203 return FALSE; |
|
204 } |
|
205 |
|
206 /** |
|
207 * Check if the network interface changed. |
|
208 * |
|
209 * @return boolean returns TRUE if the network interface has changed |
|
210 * |
|
211 * @note Most common case is for softphone clients where if a PC is |
|
212 * undocked the network interface changes from wired to wireless. |
|
213 */ |
|
214 boolean platIsNetworkInterfaceChanged() { |
|
215 //We're OK with this |
|
216 return FALSE; |
|
217 } |
|
218 |
|
219 /** |
|
220 * Get active phone load name |
|
221 * |
|
222 * Returns the phone images in the active and inactive partitions |
|
223 * The phone reports these phone loads to CUCM for display on the Admin page |
|
224 * |
|
225 * @param[in] image_a : Populate the image name from partition a |
|
226 * @param[in] image_b : Populate the image name from partition b |
|
227 * @param[in] len : Length of the pointers for image_a and image_b |
|
228 * @return 1 - image_a is active. |
|
229 * Anything other than 1 - image_b is active |
|
230 */ |
|
231 int platGetActiveInactivePhoneLoadName(char * image_a, char * image_b, int len) { |
|
232 if (image_a != nullptr) |
|
233 { |
|
234 sstrncpy(image_a, "image_a", len); |
|
235 } |
|
236 |
|
237 if (image_b != nullptr) |
|
238 { |
|
239 sstrncpy(image_b, "image_b", len); |
|
240 } |
|
241 |
|
242 return 1; |
|
243 } |
|
244 |
|
245 /** |
|
246 * Get or Set user defined phrases |
|
247 * @param index the phrase index, see |
|
248 * @param phrase the return phrase holder |
|
249 * @param len the input length to cap the maximum value |
|
250 * @return SUCCESS or FAILURE |
|
251 */ |
|
252 int platGetPhraseText(int index, char* phrase, unsigned int len) { |
|
253 //Need to copy something into "phrase" as this is used as a prefix |
|
254 //in a starts with comparison (use strncmp) that will match against |
|
255 //any string if the prefix is empty. Also in some places an |
|
256 //uninitialized buffer is passed in as "phrase", so if we don't |
|
257 //do something then SIPCC will go on the use the uninitialized |
|
258 //buffer. |
|
259 |
|
260 if (phrase == nullptr) |
|
261 { |
|
262 return CC_FAILURE; |
|
263 } |
|
264 |
|
265 sstrncpy(phrase, "?????", len); |
|
266 |
|
267 return (int) CC_SUCCESS; |
|
268 } |
|
269 |
|
270 /** |
|
271 * Get the unregistration reason code. |
|
272 * @return reason code for unregistration, see the definition. |
|
273 */ |
|
274 int platGetUnregReason() { |
|
275 return 0; |
|
276 } |
|
277 |
|
278 /** |
|
279 * Set the unregistration reason |
|
280 * @param reason see the unregister reason definitions. |
|
281 * @return void |
|
282 */ |
|
283 void platSetUnregReason(int reason) { |
|
284 //We may need to persist this for CUCM. WHen we restart next time call to platGetUnregReason above tells CUCM what why we unregistered last time. |
|
285 typedef struct _unRegRreasonEnumPair { |
|
286 int reason; |
|
287 const char * pReasonStr; |
|
288 } unRegRreasonEnumPair; |
|
289 |
|
290 static unRegRreasonEnumPair unRegReasons[] = { |
|
291 { CC_UNREG_REASON_UNSPECIFIED, "CC_UNREG_REASON_UNSPECIFIED" }, |
|
292 { CC_UNREG_REASON_TCP_TIMEOUT, "CC_UNREG_REASON_TCP_TIMEOUT" }, |
|
293 { CC_UNREG_REASON_CM_RESET_TCP, "CC_UNREG_REASON_CM_RESET_TCP" }, |
|
294 { CC_UNREG_REASON_CM_ABORTED_TCP, "CC_UNREG_REASON_CM_ABORTED_TCP" }, |
|
295 { CC_UNREG_REASON_CM_CLOSED_TCP, "C_UNREG_REASON_CM_CLOSED_TCP" }, |
|
296 { CC_UNREG_REASON_REG_TIMEOUT, "CC_UNREG_REASON_REG_TIMEOUT" }, |
|
297 { CC_UNREG_REASON_FALLBACK, "CC_UNREG_REASON_FALLBACK" }, |
|
298 { CC_UNREG_REASON_PHONE_KEYPAD, "CC_UNREG_REASON_PHONE_KEYPAD" }, |
|
299 { CC_UNREG_REASON_RESET_RESET, "CC_UNREG_REASON_RESET_RESET" }, |
|
300 { CC_UNREG_REASON_RESET_RESTART, "CC_UNREG_REASON_RESET_RESTART" }, |
|
301 { CC_UNREG_REASON_PHONE_REG_REJ, "CC_UNREG_REASON_PHONE_REG_REJ" }, |
|
302 { CC_UNREG_REASON_PHONE_INITIALIZED, "CC_UNREG_REASON_PHONE_INITIALIZED" }, |
|
303 { CC_UNREG_REASON_VOICE_VLAN_CHANGED, "CC_UNREG_REASON_VOICE_VLAN_CHANGED" }, |
|
304 { CC_UNREG_REASON_POWER_SAVE_PLUS, "CC_UNREG_REASON_POWER_SAVE_PLUS" }, |
|
305 { CC_UNREG_REASON_VERSION_STAMP_MISMATCH, "CC_UNREG_REASON_VERSION_STAMP_MISMATCH" }, |
|
306 { CC_UNREG_REASON_VERSION_STAMP_MISMATCH_CONFIG, "CC_UNREG_REASON_VERSION_STAMP_MISMATCH_CONFIG" }, |
|
307 { CC_UNREG_REASON_VERSION_STAMP_MISMATCH_SOFTKEY, "CC_UNREG_REASON_VERSION_STAMP_MISMATCH_SOFTKEY" }, |
|
308 { CC_UNREG_REASON_VERSION_STAMP_MISMATCH_DIALPLAN, "CC_UNREG_REASON_VERSION_STAMP_MISMATCH_DIALPLAN" }, |
|
309 { CC_UNREG_REASON_APPLY_CONFIG_RESTART, "CC_UNREG_REASON_APPLY_CONFIG_RESTART" }, |
|
310 { CC_UNREG_REASON_CONFIG_RETRY_RESTART, "CC_UNREG_REASON_CONFIG_RETRY_RESTART" }, |
|
311 { CC_UNREG_REASON_TLS_ERROR, "CC_UNREG_REASON_TLS_ERROR" }, |
|
312 { CC_UNREG_REASON_RESET_TO_INACTIVE_PARTITION, "CC_UNREG_REASON_RESET_TO_INACTIVE_PARTITION" }, |
|
313 { CC_UNREG_REASON_VPN_CONNECTIVITY_LOST, "CC_UNREG_REASON_VPN_CONNECTIVITY_LOST" } |
|
314 }; |
|
315 |
|
316 for (int i=0; i< (int) csf_countof(unRegReasons); i++) |
|
317 { |
|
318 unRegRreasonEnumPair * pCurrentUnRegReasonPair = &unRegReasons[i]; |
|
319 |
|
320 if (pCurrentUnRegReasonPair->reason == reason) |
|
321 { |
|
322 CSFLogDebug( logTag, "platSetUnregReason(%s)", pCurrentUnRegReasonPair->pReasonStr); |
|
323 return; |
|
324 } |
|
325 } |
|
326 |
|
327 CSFLogError( logTag, "Unknown reason code (%d) passed to platSetUnregReason()", reason); |
|
328 } |
|
329 |
|
330 |
|
331 #endif |
|
332 |
|
333 #ifndef OSX |
|
334 /** |
|
335 * Set the kpml value for application. |
|
336 * @param kpml_config the kpml value |
|
337 * @return void |
|
338 */ |
|
339 void platSetKPMLConfig(cc_kpml_config_t kpml_config) { |
|
340 } |
|
341 |
|
342 /** |
|
343 * Check if a line has active MWI status |
|
344 * @param line |
|
345 * @return boolean |
|
346 */ |
|
347 boolean platGetMWIStatus(cc_lineid_t line) { |
|
348 return TRUE; |
|
349 } |
|
350 |
|
351 |
|
352 /** |
|
353 * Secure Socket API's. |
|
354 * The pSIPCC expects the following Secure Socket APIs to be implemented in the |
|
355 * vendor porting layer. |
|
356 */ |
|
357 |
|
358 /** |
|
359 * platSecIsServerSecure |
|
360 * |
|
361 * @brief Lookup the secure status of the server |
|
362 * |
|
363 * This function looks at the the CCM server type by using the security library |
|
364 * and returns appropriate indication to the pSIPCC. |
|
365 * |
|
366 * |
|
367 * @return Server is security enabled or not |
|
368 * PLAT_SOCK_SECURE or PLAT_SOCK_NONSECURE |
|
369 * |
|
370 * @note This API maps to the following HandyIron API: |
|
371 * int secIsServerSecure(SecServerType type) where type should be SRVR_TYPE_CCM |
|
372 */ |
|
373 plat_soc_status_e platSecIsServerSecure(void) { |
|
374 return PLAT_SOCK_NONSECURE; |
|
375 } |
|
376 |
|
377 |
|
378 /** |
|
379 * platSecSocConnect |
|
380 * @brief Securely connect to a remote server |
|
381 * |
|
382 * This function uses the security library APIs to connect to a remote server. |
|
383 * @param[in] host server addr |
|
384 * @param[in] port port number |
|
385 * @param[in] ipMode IP mode to indicate v6, v4 or both |
|
386 * @param[in] mode blocking connect or not |
|
387 * FALSE: non-blocking; TRUE: blocking |
|
388 * @param[in] tos TOS value |
|
389 * @param[in] connectionType Are we talking to Call-Agent |
|
390 * @param[in] connectionMode The mode of the connection |
|
391 * (Authenticated/Encrypted) |
|
392 * @param[out] localPort local port used for the connection |
|
393 * |
|
394 * @return client socket descriptor |
|
395 * >=0: connected or in progress |
|
396 * INVALID SOCKET: failed |
|
397 * |
|
398 * @pre (hostAndPort not_eq nullptr) |
|
399 * @pre (localPort not_eq nullptr) |
|
400 * |
|
401 * @note localPort is undefined when the return value is INVALID_SOCKET |
|
402 * |
|
403 * @note This API maps to the HandyIron APIs as follows: |
|
404 * If mode == TRUE (blocking): |
|
405 * int secEstablishSecureConnection(const char* serverAddr, *uint32_t port, secConnectionType type) |
|
406 * @li ipMode is UNUSED |
|
407 * @li "host" maps to "serverAddr", "connectionType" maps to "type" |
|
408 * @li localPort is passed in as 0 |
|
409 * If mode == FALSE (non-blocking): |
|
410 * int secConnect(const char* serverAddr, uint32_t port, *secConnectionType type, uint32_t localPort) |
|
411 * @li ipMode is UNUSED |
|
412 * @li "host" maps to "serverAddr", "connectionType" maps to "type" |
|
413 * |
|
414 * @note The implementation should use the "setsockopt" to set the "tos" value passed |
|
415 * in this API on the created socket. |
|
416 * |
|
417 */ |
|
418 cpr_socket_t |
|
419 platSecSocConnect (char *host, |
|
420 int port, |
|
421 int ipMode, |
|
422 boolean mode, |
|
423 unsigned int tos, |
|
424 plat_soc_connect_mode_e connectionMode, |
|
425 uint16_t *localPort) { |
|
426 return 0; |
|
427 } |
|
428 |
|
429 /** |
|
430 * platSecSockIsConnected |
|
431 * Determine the status of a secure connection that was initiated |
|
432 * in non-blocking mode |
|
433 * |
|
434 * @param[in] sock socket descriptor |
|
435 * |
|
436 * @return connection status |
|
437 * @li connection complete: PLAT_SOCK_CONN_OK |
|
438 * @li connection waiting: PLAT_SOCK_CONN_WAITING |
|
439 * @li connection failed: PLAT_SOCK_CONN_FAILED |
|
440 * |
|
441 * @note This API maps to the following HandyIron API: |
|
442 * int secIsConnectionReady (int connDesc) |
|
443 * The "sock" is the connection descriptor. |
|
444 */ |
|
445 plat_soc_connect_status_e platSecSockIsConnected (cpr_socket_t sock) { |
|
446 return PLAT_SOCK_CONN_OK; |
|
447 } |
|
448 #endif //#endif !OSX |
|
449 |
|
450 /** |
|
451 * platGenerateCryptoRand |
|
452 * @brief Generates a Random Number |
|
453 * |
|
454 * Generate crypto graphically random number for a desired length. |
|
455 * The function is expected to be much slower than the cpr_rand(). |
|
456 * This function should be used when good random number is needed |
|
457 * such as random number that to be used for SRTP key for an example. |
|
458 * |
|
459 * @param[in] buf - pointer to the buffer to store the result of random |
|
460 * bytes requested. |
|
461 * @param[in] len - pointer to the length of the desired random bytes. |
|
462 * When calling the function, the integer's value |
|
463 * should be set to the desired number of random |
|
464 * bytes ('buf' should be of at least this size). |
|
465 * upon success, its value will be set to the |
|
466 * actual number of random bytes being returned. |
|
467 * (realistically, there is a maximum number of |
|
468 * random bytes that can be returned at a time. |
|
469 * if the caller request more than that, the |
|
470 * 'len' will indicate how many bytes are actually being |
|
471 * returned) on failure, its value will be set to 0. |
|
472 * |
|
473 * @return |
|
474 * 1 - success. |
|
475 * 0 - fail. |
|
476 * |
|
477 * @note The intent of this function is to generate a cryptographically strong |
|
478 * random number. Vendors can map this to HandyIron or OpenSSL random number |
|
479 * generation functions. |
|
480 * |
|
481 * @note This API maps to the following HandyIron API: |
|
482 * int secGetRandomData(uint8_t *buf, uint32_t size). Also note that a |
|
483 * "secAddEntropy(...)" may be required the first time to feed entropy data to |
|
484 * the random number generator. |
|
485 */ |
|
486 #ifdef LINUX |
|
487 int platGenerateCryptoRand(uint8_t *buf, int *len) { |
|
488 int fd; |
|
489 int rc = 0; |
|
490 ssize_t s; |
|
491 |
|
492 if ((fd = open("/dev/urandom", O_RDONLY)) == -1) { |
|
493 CSFLogDebug( logTag, "Failed to open prng driver"); |
|
494 return 0; |
|
495 } |
|
496 |
|
497 /* |
|
498 * Try to read the given amount of bytes from the PRNG device. We do not |
|
499 * handle short reads but just return the number of bytes read from the |
|
500 * device. The caller has to manage this. |
|
501 * E.g. gsmsdp_generate_key() in core/gsm/gsm_sdp_crypto.c |
|
502 */ |
|
503 |
|
504 s = read(fd, buf, (size_t) *len); |
|
505 |
|
506 if (s > 0) { |
|
507 *len = s; |
|
508 rc = 1; /* Success */ |
|
509 } else { |
|
510 *len = 0; |
|
511 rc = 0; /* Failure */ |
|
512 } |
|
513 |
|
514 |
|
515 (void) close(fd); |
|
516 return rc; |
|
517 } |
|
518 #else |
|
519 int platGenerateCryptoRand(uint8_t *buf, int *len) { |
|
520 return 0; |
|
521 } |
|
522 #endif//!LINUX |
|
523 |
|
524 #ifndef OSX |
|
525 |
|
526 /* |
|
527 <Umesh> The version is to regulate certain features like Join, which are added in later releases. |
|
528 This is exchanged during registration with CUCM. It is a sheer luck that join may be working in some cases. |
|
529 In this case Set API you have to store each of those API and return the same value in get. |
|
530 |
|
531 We can go over all platform API’ and see which one are mandatory, we can do this in an email or in a meeting. |
|
532 Please send out list methods for which you need clarification. |
|
533 */ |
|
534 static cc_uint32_t majorSIS=1, minorSIS=0, addtnlSIS =0; |
|
535 static char sis_ver_name[CC_MAX_LEN_REQ_SUPP_PARAM_CISCO_SISTAG] = {0}; |
|
536 |
|
537 /** |
|
538 * Sets the SIS protocol version |
|
539 * |
|
540 * @param a - major version |
|
541 * @param b - minor version |
|
542 * @param c - additional version information |
|
543 * @param name - version name |
|
544 * |
|
545 * @return void |
|
546 * @note the platform should store this information and provide it when asked via the platGetSISProtocolVer() |
|
547 */ |
|
548 void platSetSISProtocolVer(cc_uint32_t a, cc_uint32_t b, cc_uint32_t c, char* name) { |
|
549 majorSIS = a; |
|
550 minorSIS = b; |
|
551 addtnlSIS = c; |
|
552 |
|
553 if (name) { |
|
554 sstrncpy(sis_ver_name, name, csf_countof(sis_ver_name)); |
|
555 } else { |
|
556 *sis_ver_name = '\0'; |
|
557 } |
|
558 } |
|
559 |
|
560 /** |
|
561 * Provides the SIS protocol version |
|
562 * |
|
563 * @param *a pointer to fill in the major version |
|
564 * @param *b pointer to fill in the minor version |
|
565 * @param *c pointer to fill in the additonal version |
|
566 * @param *name pointer to fill in the version name |
|
567 * |
|
568 * @return void |
|
569 */ |
|
570 void |
|
571 platGetSISProtocolVer (cc_uint32_t *a, cc_uint32_t *b, cc_uint32_t *c, char* name) { |
|
572 |
|
573 if (a != nullptr) |
|
574 { |
|
575 *a = majorSIS; |
|
576 } |
|
577 |
|
578 if (b != nullptr) |
|
579 { |
|
580 *b = minorSIS; |
|
581 } |
|
582 |
|
583 if (c != nullptr) |
|
584 { |
|
585 *c = addtnlSIS; |
|
586 } |
|
587 |
|
588 if (name != nullptr) |
|
589 { |
|
590 sstrncpy(name, sis_ver_name, CC_MAX_LEN_REQ_SUPP_PARAM_CISCO_SISTAG); |
|
591 } |
|
592 |
|
593 return; |
|
594 } |
|
595 |
|
596 void debug_bind_keyword(const char *cmd, int32_t *flag_ptr) { |
|
597 return; |
|
598 } |
|
599 |
|
600 void debugif_add_keyword(const char *x, const char *y) { |
|
601 return; |
|
602 } |
|
603 #endif |
|
604 |
|
605 // Keep this when we are building the sipcc library without it, so that we capture logging |
|
606 int debugif_printf(const char *_format, ...) { |
|
607 va_list ap; |
|
608 va_start(ap, _format); |
|
609 CSFLogDebugV( logTag, _format, ap); |
|
610 va_end(ap); |
|
611 return 1; // Fake a "happy" return value. |
|
612 } |
|
613 |
|
614 } |
|
615 |