void sip_platform_handle_service_control_notify (sipServiceControl_t *scp) { switch (scp->action) { case SERVICE_CONTROL_ACTION_RESET: platform_reset_req(DEVICE_RESET); break; case SERVICE_CONTROL_ACTION_RESTART: platform_reset_req(DEVICE_RESTART); break; case SERVICE_CONTROL_ACTION_CHECK_VERSION: platform_sync_cfg_vers(scp->configVersionStamp, scp->dialplanVersionStamp, scp->softkeyVersionStamp); break; case SERVICE_CONTROL_ACTION_APPLY_CONFIG: // call the function to process apply config NOTIFY message. platform_apply_config(scp->configVersionStamp, scp->dialplanVersionStamp, scp->fcpVersionStamp, scp->cucm_result, scp->firmwareLoadId, scp->firmwareInactiveLoadId, scp->loadServer, scp->logServer, scp->ppid); break; default: break; } }
/** * * sip_platform_task_loop * * Run the SIP task * * Parameters: arg - SIP message queue * * Return Value: None * */ void sip_platform_task_loop (void *arg) { static const char *fname = "sip_platform_task_loop"; int pending_operations; uint16_t i; fd_set sip_read_fds; fd_set sip_write_fds; sip_tcp_conn_t *entry; sip_msgq = (cprMsgQueue_t) arg; if (!sip_msgq) { CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_msgq is null, exiting", fname); return; } sip.msgQueue = sip_msgq; sip_platform_task_init(); /* * Initialize the SIP task */ SIPTaskInit(); if (platThreadInit("SIPStack Task") != 0) { CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM", fname); return; } /* * Adjust relative priority of SIP thread. */ (void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY); /* * Setup IPC socket addresses for main thread (server) */ { char stmpdir[sizeof(sip_serv_sock_addr.sun_path)]; sip_get_sock_dir(stmpdir, sizeof(stmpdir), SIP_MSG_SERV_SUFFIX); cpr_set_sockun_addr(&sip_serv_sock_addr, stmpdir, 0); } /* * Create IPC between the message queue thread and this main * thread. */ sip_ipc_serv_socket = sip_create_IPC_sock(sip_serv_sock_addr.sun_path); if (sip_ipc_serv_socket == INVALID_SOCKET) { CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_create_IPC_sock() failed:" " errno=%d\n", fname, cpr_errno); return; } /* * On Win32 platform, the random seed is stored per thread; therefore, * each thread needs to seed the random number. It is recommended by * MS to do the following to ensure randomness across application * restarts. */ cpr_srand((unsigned int)time(NULL)); /* * Set read IPC socket */ sip_platform_task_set_read_socket(sip_ipc_serv_socket); /* * Let the message queue waiting thread know that the main * thread is ready. */ main_thread_ready = TRUE; /* * Main Event Loop * - Forever-loop exits in sip_process_int_msg()::THREAD_UNLOAD */ while (TRUE) { /* * Wait on events or timeout */ sip_read_fds = read_fds; // start off by init to zero FD_ZERO(&sip_write_fds); // now look for sockets where data has been queued up for (i = 0; i < MAX_CONNECTIONS; i++) { entry = sip_tcp_conn_tab + i; if (-1 != entry->fd && entry->sendQueue && sll_count(entry->sendQueue)) { FD_SET(entry->fd, &sip_write_fds); } } pending_operations = cprSelect((nfds + 1), &sip_read_fds, &sip_write_fds, NULL, NULL); if (pending_operations == SOCKET_ERROR) { CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSelect() failed: errno=%d." " Recover by initiating sip restart\n", fname, cpr_errno); /* * If we have come here, then either read socket related to * sip_ipc_serv_socket has got corrupted, or one of the write * socket related to cucm tcp/tls connection. * We will recover, by first clearing all fds, then re-establishing * the connection with sip-msgq by listening on * sip_ipc_serv_socket. */ sip_platform_task_init(); /* this clear FDs */ sip_platform_task_set_read_socket(sip_ipc_serv_socket); /* * Since all sockets fds have been cleared above, we can not anyway * send or receive msg from cucm. So, there is no point * trying to send registration cancel msg to cucm. Also, a * call may be active, and in that case we do not want to * un-register. So, by setting sip_reg_all_failed to true, we * make sure that no registration cancelation attempt is made. */ sip_reg_all_failed = TRUE; platform_reset_req(DEVICE_RESTART); continue; } else if (pending_operations) { /* * Listen socket is set only if UDP transport has been * configured. So see if the select return was for read * on the listen socket. */ if ((listen_socket != INVALID_SOCKET) && (sip.taskInited == TRUE) && FD_ISSET(listen_socket, &sip_read_fds)) { sip_platform_udp_read_socket(listen_socket); pending_operations--; } /* * Check IPC for internal message queue */ if (FD_ISSET(sip_ipc_serv_socket, &sip_read_fds)) { /* read the message to flush the buffer */ sip_process_int_msg(); pending_operations--; } /* * Check all sockets for stuff to do */ for (i = 0; ((i < MAX_SIP_CONNECTIONS) && (pending_operations > 0)); i++) { if ((sip_conn.read[i] != INVALID_SOCKET) && FD_ISSET(sip_conn.read[i], &sip_read_fds)) { /* * Assume tcp */ sip_tcp_read_socket(sip_conn.read[i]); pending_operations--; } if ((sip_conn.write[i] != INVALID_SOCKET) && FD_ISSET(sip_conn.write[i], &sip_write_fds)) { int connid; connid = sip_tcp_fd_to_connid(sip_conn.write[i]); if (connid >= 0) { sip_tcp_resend(connid); } pending_operations--; } } } } }