* \brief get a cookie to grab rig control * \param rig Not used * \param cookie_cmd The command to execute on \a cookie. * \param cookie The cookie to operate on, cannot be NULL or RIG_EINVAL will be returned. * \param cookie_len The length of the cookie, must be #HAMLIB_COOKIE_SIZE or larger. * * #RIG_COOKIE_GET will set \a cookie with a cookie. * #RIG_COOKIE_RENEW will update the ti
| 8310 | * \endcode |
| 8311 | */ |
| 8312 | int HAMLIB_API rig_cookie(RIG *rig, enum cookie_e cookie_cmd, char *cookie, |
| 8313 | int cookie_len) |
| 8314 | { |
| 8315 | // only 1 client can have the cookie so these can be static |
| 8316 | // this should also prevent problems with DLLs & shared libraries |
| 8317 | // the debug_msg is another non-thread-safe which this will help fix |
| 8318 | static char |
| 8319 | cookie_save[HAMLIB_COOKIE_SIZE]; // only one client can have the cookie |
| 8320 | static double time_last_used; |
| 8321 | struct timespec tp; |
| 8322 | int ret; |
| 8323 | MUTEX(mutex_rig_cookie); |
| 8324 | |
| 8325 | /* This is not needed for RIG_COOKIE_RELEASE but keep it simple. */ |
| 8326 | if (cookie_len < HAMLIB_COOKIE_SIZE) |
| 8327 | { |
| 8328 | rig_debug(RIG_DEBUG_ERR, "%s(%d): cookie_len < %d\n", |
| 8329 | __FILE__, __LINE__, HAMLIB_COOKIE_SIZE); |
| 8330 | return -RIG_EINVAL; |
| 8331 | } |
| 8332 | |
| 8333 | if (!cookie) |
| 8334 | { |
| 8335 | rig_debug(RIG_DEBUG_ERR, "%s(%d): cookie == NULL\n", |
| 8336 | __FILE__, __LINE__); |
| 8337 | return -RIG_EINVAL; // nothing to do |
| 8338 | } |
| 8339 | |
| 8340 | /* Accessing cookie_save and time_last_used must be done with lock held. |
| 8341 | * So keep code simple and lock it during the whole operation. */ |
| 8342 | MUTEX_LOCK(mutex_rig_cookie); |
| 8343 | |
| 8344 | switch (cookie_cmd) |
| 8345 | { |
| 8346 | case RIG_COOKIE_RELEASE: |
| 8347 | if (cookie_save[0] != 0 |
| 8348 | && strcmp(cookie, cookie_save) == 0) // matching cookie so we'll clear it |
| 8349 | { |
| 8350 | rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %s cookie released\n", |
| 8351 | __FILE__, __LINE__, cookie_save); |
| 8352 | memset(cookie_save, 0, sizeof(cookie_save)); |
| 8353 | ret = RIG_OK; |
| 8354 | } |
| 8355 | else // not the right cookie!! |
| 8356 | { |
| 8357 | rig_debug(RIG_DEBUG_ERR, |
| 8358 | "%s(%d): %s can't release cookie as cookie %s is active\n", __FILE__, __LINE__, |
| 8359 | cookie, cookie_save); |
| 8360 | ret = -RIG_BUSBUSY; |
| 8361 | } |
| 8362 | |
| 8363 | break; |
| 8364 | |
| 8365 | case RIG_COOKIE_RENEW: |
| 8366 | rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %s comparing renew request to %s==%d\n", |
| 8367 | __FILE__, __LINE__, cookie, cookie_save, strcmp(cookie, cookie_save)); |
| 8368 | |
| 8369 | if (cookie_save[0] != 0 |