mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-14 08:05:37 +00:00
skypiax: patch from Seven Du for hunting IDLE channels in a round-robin way (RR interface vs ANY interface). patch from Seven Du for removing interface as #'interface_id' and #'interface_name'. gmaruzz (meh) patch interface_remove() not to alter the global 'running' variable (it would cause all running signaling and API thread to exit) but to use a newly added tech_pvt->running variable. Also, changed behavior of interface_exists() for correct identification when using #interface_name and #interface_id. PLEASE TEST IT HEAVILY
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14410 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
f4b2efba87
commit
506d3768a1
@ -86,7 +86,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypiax_shutdown);
|
||||
SWITCH_MODULE_DEFINITION(mod_skypiax, mod_skypiax_load, mod_skypiax_shutdown, NULL);
|
||||
SWITCH_STANDARD_API(sk_function);
|
||||
/* BEGIN: Changes here */
|
||||
#define SK_SYNTAX "list || reload || console || remove interface_name || skype_API_msg"
|
||||
#define SK_SYNTAX "list [full] || console || skype_API_msg || remove <skypeusername | #interface_name | #interface_id> || reload"
|
||||
/* END: Changes heres */
|
||||
SWITCH_STANDARD_API(skypiax_function);
|
||||
#define SKYPIAX_SYNTAX "interface_name skype_API_msg"
|
||||
@ -111,7 +111,9 @@ static struct {
|
||||
int codec_rates_last;
|
||||
unsigned int flags;
|
||||
int fd;
|
||||
int calls;
|
||||
int calls;
|
||||
int real_interfaces;
|
||||
int next_interface;
|
||||
char hold_music[256];
|
||||
private_t SKYPIAX_INTERFACES[SKYPIAX_MAX_INTERFACES];
|
||||
switch_mutex_t *mutex;
|
||||
@ -211,20 +213,45 @@ void skypiax_tech_init(private_t * tech_pvt, switch_core_session_t * session)
|
||||
}
|
||||
|
||||
/* BEGIN: Changes here */
|
||||
static switch_status_t interface_exists(char *skype_user)
|
||||
static switch_status_t interface_exists(char *interface)
|
||||
{
|
||||
int i;
|
||||
int interface_id;
|
||||
|
||||
if ( *interface == '#') { /* look by interface id or interface name */
|
||||
interface++;
|
||||
switch_assert(interface);
|
||||
interface_id = atoi(interface);
|
||||
|
||||
/* take a number as interface id */
|
||||
if ( interface_id > 0 || (interface_id == 0 && strcmp(interface, "0") == 0 )) {
|
||||
if (strlen(globals.SKYPIAX_INTERFACES[interface_id].name)) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
|
||||
for (interface_id = 0; interface_id < SKYPIAX_MAX_INTERFACES; interface_id++) {
|
||||
if (strcmp(globals.SKYPIAX_INTERFACES[interface_id].name, interface) == 0) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* look by skype_user */
|
||||
|
||||
|
||||
for (i = 0; i < SKYPIAX_MAX_INTERFACES; i++) {
|
||||
if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
|
||||
if (strcmp(globals.SKYPIAX_INTERFACES[i].skype_user, skype_user) == 0) {
|
||||
if (strcmp(globals.SKYPIAX_INTERFACES[i].name, interface) == 0) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static switch_status_t remove_interface(char *skype_user)
|
||||
static switch_status_t remove_interface(char *interface)
|
||||
{
|
||||
int x = 100;
|
||||
unsigned int howmany = 8;
|
||||
@ -232,26 +259,48 @@ static switch_status_t remove_interface(char *skype_user)
|
||||
private_t *tech_pvt = NULL;
|
||||
switch_status_t status;
|
||||
|
||||
running = 0;
|
||||
//running = 0;
|
||||
|
||||
for (interface_id = 0; interface_id < SKYPIAX_MAX_INTERFACES; interface_id++) {
|
||||
if (strcmp(globals.SKYPIAX_INTERFACES[interface_id].skype_user, skype_user) == 0) {
|
||||
|
||||
if ( *interface == '#') { /* remove by interface id or interface name */
|
||||
interface++;
|
||||
switch_assert(interface);
|
||||
interface_id = atoi(interface);
|
||||
|
||||
if ( interface_id > 0 || (interface_id == 0 && strcmp(interface, "0") == 0 )) {
|
||||
/* take a number as interface id */
|
||||
tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id];
|
||||
break;
|
||||
} else {
|
||||
|
||||
for (interface_id = 0; interface_id < SKYPIAX_MAX_INTERFACES; interface_id++) {
|
||||
if (strcmp(globals.SKYPIAX_INTERFACES[interface_id].name, interface) == 0) {
|
||||
tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* remove by skype_user */
|
||||
for (interface_id = 0; interface_id < SKYPIAX_MAX_INTERFACES; interface_id++) {
|
||||
if (strcmp(globals.SKYPIAX_INTERFACES[interface_id].skype_user, interface) == 0) {
|
||||
tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!tech_pvt) {
|
||||
DEBUGA_SKYPE("interface for skype user '%s' does not exist\n", SKYPIAX_P_LOG,
|
||||
skype_user);
|
||||
DEBUGA_SKYPE("interface '%s' does not exist\n", SKYPIAX_P_LOG,
|
||||
interface);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strlen(globals.SKYPIAX_INTERFACES[interface_id].session_uuid_str)) {
|
||||
DEBUGA_SKYPE("interface for skype user '%s' is busy\n", SKYPIAX_P_LOG, skype_user);
|
||||
DEBUGA_SKYPE("interface '%s' is busy\n", SKYPIAX_P_LOG, interface);
|
||||
goto end;
|
||||
}
|
||||
|
||||
globals.SKYPIAX_INTERFACES[interface_id].running=0;
|
||||
|
||||
if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread) {
|
||||
#ifdef WIN32
|
||||
switch_file_write(tech_pvt->SkypiaxHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die
|
||||
@ -300,10 +349,16 @@ static switch_status_t remove_interface(char *skype_user)
|
||||
}
|
||||
|
||||
memset(&globals.SKYPIAX_INTERFACES[interface_id], '\0', sizeof(private_t));
|
||||
DEBUGA_SKYPE("interface for skype user '%s' deleted successfully\n", SKYPIAX_P_LOG,
|
||||
skype_user);
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
globals.real_interfaces--;
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
DEBUGA_SKYPE("interface '%s' deleted successfully\n", SKYPIAX_P_LOG,
|
||||
interface);
|
||||
globals.SKYPIAX_INTERFACES[interface_id].running=1;
|
||||
end:
|
||||
running = 1;
|
||||
//running = 1;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -333,6 +388,7 @@ static switch_status_t channel_on_init(switch_core_session_t * session)
|
||||
switch_channel_set_state(channel, CS_ROUTING);
|
||||
switch_mutex_lock(globals.mutex);
|
||||
globals.calls++;
|
||||
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
DEBUGA_SKYPE("%s CHANNEL INIT\n", SKYPIAX_P_LOG, switch_channel_get_name(channel));
|
||||
@ -716,9 +772,14 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t * sess
|
||||
/* we've been asked for the "ANY" interface, let's find the first idle interface */
|
||||
DEBUGA_SKYPE("Finding one available skype interface\n", SKYPIAX_P_LOG);
|
||||
tech_pvt = find_available_skypiax_interface(NULL);
|
||||
if (tech_pvt)
|
||||
found = 1;
|
||||
if (tech_pvt) found = 1;
|
||||
} else if(strncmp("RR", interface_name, strlen(interface_name)) == 0) {
|
||||
/* Find the first idle interface using Round Robin */
|
||||
DEBUGA_SKYPE("Finding one available skype interface RR\n", SKYPIAX_P_LOG);
|
||||
tech_pvt = find_available_skypiax_interface_rr();
|
||||
if (tech_pvt) found = 1;
|
||||
}
|
||||
|
||||
for (i = 0; !found && i < SKYPIAX_MAX_INTERFACES; i++) {
|
||||
/* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */
|
||||
if (strlen(globals.SKYPIAX_INTERFACES[i].name)
|
||||
@ -815,7 +876,7 @@ static void *SWITCH_THREAD_FUNC skypiax_signaling_thread_func(switch_thread_t *
|
||||
(void *) tech_pvt);
|
||||
|
||||
while (forever) {
|
||||
if (!running)
|
||||
if (!(running && tech_pvt->running))
|
||||
break;
|
||||
res = skypiax_signaling_read(tech_pvt);
|
||||
if (res == CALLFLOW_INCOMING_HANGUP) {
|
||||
@ -983,7 +1044,7 @@ static switch_status_t load_config(int reload_type)
|
||||
|
||||
/* BEGIN: Changes here */
|
||||
if (reload_type == SOFT_RELOAD) {
|
||||
if (interface_exists(skype_user) == SWITCH_STATUS_SUCCESS) {
|
||||
if (interface_exists(name) == SWITCH_STATUS_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1049,6 +1110,8 @@ static switch_status_t load_config(int reload_type)
|
||||
|
||||
memset(&newconf, '\0', sizeof(newconf));
|
||||
globals.SKYPIAX_INTERFACES[interface_id] = newconf;
|
||||
globals.SKYPIAX_INTERFACES[interface_id].running = 1;
|
||||
|
||||
|
||||
tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id];
|
||||
|
||||
@ -1189,6 +1252,9 @@ static switch_status_t load_config(int reload_type)
|
||||
|
||||
for (i = 0; i < SKYPIAX_MAX_INTERFACES; i++) {
|
||||
if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
|
||||
/* How many real intterfaces */
|
||||
globals.real_interfaces = i + 1;
|
||||
|
||||
tech_pvt = &globals.SKYPIAX_INTERFACES[i];
|
||||
|
||||
DEBUGA_SKYPE("i=%d globals.SKYPIAX_INTERFACES[%d].interface_id=%s\n",
|
||||
@ -1550,6 +1616,48 @@ private_t *find_available_skypiax_interface(private_t * tech_pvt)
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private_t *find_available_skypiax_interface_rr(void)
|
||||
{
|
||||
private_t *tech_pvt = NULL;
|
||||
int i;
|
||||
/* int num_interfaces = SKYPIAX_MAX_INTERFACES; */
|
||||
int num_interfaces = globals.real_interfaces;
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
|
||||
/* Fact is the real interface start from 1 */
|
||||
if (globals.next_interface == 0) globals.next_interface = 1;
|
||||
|
||||
for (i = 0; i < num_interfaces; i++) {
|
||||
int interface_id;
|
||||
|
||||
interface_id = globals.next_interface + i;
|
||||
interface_id = interface_id < num_interfaces ? interface_id : interface_id - num_interfaces + 1;
|
||||
|
||||
if (strlen(globals.SKYPIAX_INTERFACES[interface_id].name)) {
|
||||
int skype_state = 0;
|
||||
|
||||
tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id];
|
||||
skype_state = tech_pvt->interface_state;
|
||||
DEBUGA_SKYPE("skype interface: %d, name: %s, state: %d\n", SKYPIAX_P_LOG, interface_id,
|
||||
globals.SKYPIAX_INTERFACES[interface_id].name, skype_state);
|
||||
if (SKYPIAX_STATE_DOWN == skype_state || 0 == skype_state) {
|
||||
/*set to Dialing state to avoid other thread fint it, don't know if it is safe */
|
||||
tech_pvt->interface_state = SKYPIAX_STATE_DIALING ;
|
||||
|
||||
globals.next_interface = interface_id + 1 < num_interfaces ? interface_id + 1 : 1;
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
return tech_pvt;
|
||||
}
|
||||
} else {
|
||||
DEBUGA_SKYPE("Skype interface: %d blank!! A hole here means we cannot hunt the last interface.\n", SKYPIAX_P_LOG, interface_id);
|
||||
}
|
||||
}
|
||||
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(sk_function)
|
||||
{
|
||||
@ -1571,21 +1679,32 @@ SWITCH_STANDARD_API(sk_function)
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "list")) {
|
||||
int i;
|
||||
int i;
|
||||
char next_flag_char = ' ';
|
||||
|
||||
for (i = 0; i < SKYPIAX_MAX_INTERFACES; i++) {
|
||||
next_flag_char = i == globals.next_interface ? '*' : ' ';
|
||||
|
||||
if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
|
||||
if (strlen(globals.SKYPIAX_INTERFACES[i].session_uuid_str)) {
|
||||
stream->write_function(stream,
|
||||
"globals.SKYPIAX_INTERFACES[%d].name=\t|||%s||| is \tBUSY, session_uuid_str=|||%s|||\n",
|
||||
"%c\t%d\t[%s]\tBUSY, session_uuid_str=|||%s|||\n",
|
||||
next_flag_char,
|
||||
i, globals.SKYPIAX_INTERFACES[i].name,
|
||||
globals.SKYPIAX_INTERFACES[i].session_uuid_str);
|
||||
} else {
|
||||
stream->write_function(stream,
|
||||
"globals.SKYPIAX_INTERFACES[%d].name=\t|||%s||| is \tIDLE\n",
|
||||
"%c\t%d\t[%s]\tIDLE\n",
|
||||
next_flag_char,
|
||||
i, globals.SKYPIAX_INTERFACES[i].name);
|
||||
}
|
||||
}
|
||||
} else if(argc > 1 && !strcasecmp(argv[1], "full")) {
|
||||
stream->write_function(stream, "%c\t%d\n", next_flag_char, i);
|
||||
}
|
||||
|
||||
}
|
||||
stream->write_function(stream, "\nTotal: %d\n", globals.real_interfaces - 1 );
|
||||
|
||||
} else if (!strcasecmp(argv[0], "console")) {
|
||||
int i;
|
||||
int found = 0;
|
||||
|
@ -238,6 +238,7 @@ struct private_object {
|
||||
struct timeval transfer_time;
|
||||
char transfer_callid_number[50];
|
||||
char skype_transfer_call_id[512];
|
||||
int running;
|
||||
};
|
||||
|
||||
typedef struct private_object private_t;
|
||||
@ -276,6 +277,7 @@ int skypiax_pipe_write(int pipe, short *buf, int howmany);
|
||||
#endif /* WIN32 */
|
||||
int skypiax_close_socket(unsigned int fd);
|
||||
private_t *find_available_skypiax_interface(private_t * tech_pvt);
|
||||
private_t *find_available_skypiax_interface_rr(void);
|
||||
int remote_party_is_ringing(private_t * tech_pvt);
|
||||
int remote_party_is_early_media(private_t * tech_pvt);
|
||||
int skypiax_answer(private_t * tech_pvt, char *id, char *value);
|
||||
|
@ -489,7 +489,7 @@ void *skypiax_do_tcp_srv_thread_func(void *obj)
|
||||
fd_set fsgio;
|
||||
struct timeval togio;
|
||||
|
||||
if (!running)
|
||||
if (!(running && tech_pvt->running))
|
||||
break;
|
||||
FD_ZERO(&fsgio);
|
||||
togio.tv_usec = 20000; //20msec
|
||||
@ -506,7 +506,7 @@ void *skypiax_do_tcp_srv_thread_func(void *obj)
|
||||
while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
|
||||
DEBUGA_SKYPE("ACCEPTED here I send you %d\n", SKYPIAX_P_LOG,
|
||||
tech_pvt->tcp_srv_port);
|
||||
if (!running)
|
||||
if (!(running && tech_pvt->running))
|
||||
break;
|
||||
while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
|
||||
&& (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
|
||||
@ -519,7 +519,7 @@ void *skypiax_do_tcp_srv_thread_func(void *obj)
|
||||
fd_set fs;
|
||||
struct timeval to;
|
||||
|
||||
if (!running)
|
||||
if (!(running && tech_pvt->running))
|
||||
break;
|
||||
//exit = 1;
|
||||
|
||||
@ -677,7 +677,7 @@ void *skypiax_do_tcp_cli_thread_func(void *obj)
|
||||
fd_set fsgio;
|
||||
struct timeval togio;
|
||||
|
||||
if (!running)
|
||||
if (!(running && tech_pvt->running))
|
||||
break;
|
||||
FD_ZERO(&fsgio);
|
||||
togio.tv_usec = 20000; //20msec
|
||||
@ -698,7 +698,7 @@ void *skypiax_do_tcp_cli_thread_func(void *obj)
|
||||
fcntl(tech_pvt->audioskypepipe[0], F_SETFL, O_NONBLOCK);
|
||||
#endif //WIN32
|
||||
|
||||
if (!running)
|
||||
if (!(running && tech_pvt->running))
|
||||
break;
|
||||
while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
|
||||
&& (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
|
||||
@ -710,7 +710,7 @@ void *skypiax_do_tcp_cli_thread_func(void *obj)
|
||||
fd_set fs;
|
||||
struct timeval to;
|
||||
|
||||
if (!running)
|
||||
if (!(running && tech_pvt->running))
|
||||
break;
|
||||
FD_ZERO(&fs);
|
||||
to.tv_usec = 120000; //120msec
|
||||
@ -1238,9 +1238,9 @@ void *skypiax_do_skypeapi_thread_func(void *obj)
|
||||
(WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, 0) != 0) {
|
||||
tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle =
|
||||
tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle;
|
||||
while (running) {
|
||||
while (running && tech_pvt->running) {
|
||||
MSG oMessage;
|
||||
if (!running)
|
||||
if (! (running && tech_pvt->running))
|
||||
break;
|
||||
while (GetMessage(&oMessage, 0, 0, 0)) {
|
||||
TranslateMessage(&oMessage);
|
||||
@ -1264,7 +1264,7 @@ int X11_errors_handler(Display * dpy, XErrorEvent * err)
|
||||
private_t *tech_pvt = NULL;
|
||||
|
||||
xerror = err->error_code;
|
||||
ERRORA("Received error code %d from X Server\n\n", SKYPIAX_P_LOG, xerror);
|
||||
ERRORA("Received error code %d from X Server\n\n", SKYPIAX_P_LOG, xerror); ///FIXME why crash the entire skypiax? just crash the interface, instead
|
||||
running = 0;
|
||||
return 0; /* ignore the error */
|
||||
}
|
||||
@ -1489,7 +1489,7 @@ void *skypiax_do_skypeapi_thread_func(void *obj)
|
||||
|
||||
while (1) {
|
||||
XNextEvent(disp, &an_event);
|
||||
if (!running)
|
||||
if (! (running && tech_pvt->running))
|
||||
break;
|
||||
switch (an_event.type) {
|
||||
case ClientMessage:
|
||||
@ -1557,7 +1557,7 @@ void *skypiax_do_skypeapi_thread_func(void *obj)
|
||||
running = 0;
|
||||
return NULL;
|
||||
}
|
||||
running = 0;
|
||||
//running = 0;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user