]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Skinny: rewrite of the skinny state machine
authorMathieu Parent <math.parent@gmail.com>
Thu, 20 May 2010 13:10:33 +0000 (15:10 +0200)
committerMathieu Parent <math.parent@gmail.com>
Thu, 20 May 2010 13:16:08 +0000 (15:16 +0200)
- for incoming calls, go CS_ROUTING only when number is dialed.
  CS_HIBERNATE before
- start media when both side have answered

Also:
- send tone for UNALLOCATED_NUMBER and USER_BUSY
- if channel variables are not sufficent to set call info, ask the
  partner channel

src/mod/endpoints/mod_skinny/mod_skinny.c
src/mod/endpoints/mod_skinny/mod_skinny.h
src/mod/endpoints/mod_skinny/skinny_protocol.c
src/mod/endpoints/mod_skinny/skinny_protocol.h
src/mod/endpoints/mod_skinny/skinny_server.c
src/mod/endpoints/mod_skinny/skinny_server.h

index 0dcc6ac16738bcf905f80f9e409afa87afd80db1..f414c96998ef5aa2f29c5ee7180072a184309863 100644 (file)
@@ -561,24 +561,104 @@ void tech_init(private_t *tech_pvt, skinny_profile_t *profile, switch_core_sessi
 switch_status_t channel_on_init(switch_core_session_t *session)
 {
        switch_channel_t *channel = switch_core_session_get_channel(session);
-       private_t *tech_pvt = switch_core_session_get_private(session);
-
-       switch_set_flag_locked(tech_pvt, TFLAG_IO);
-
-       /* Move channel's state machine to ROUTING. This means the call is trying
-          to get from the initial start where the call because, to the point
-          where a destination has been identified. If the channel is simply
-          left in the initial state, nothing will happen. */
-       switch_channel_set_state(channel, CS_ROUTING);
 
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL INIT\n", switch_channel_get_name(channel));
 
        return SWITCH_STATUS_SUCCESS;
 }
 
+struct channel_on_routing_helper {
+       private_t *tech_pvt;
+       listener_t *listener;
+       uint32_t line_instance;
+};
+
+int channel_on_routing_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+       struct channel_on_routing_helper *helper = pArg;
+       listener_t *listener = NULL;
+
+       char *device_name = argv[0];
+       uint32_t device_instance = atoi(argv[1]);
+       /* uint32_t position = atoi(argv[2]); */
+       uint32_t line_instance = atoi(argv[3]);
+       /* char *label = argv[4]; */
+       /* char *value = argv[5]; */
+       /* char *caller_name = argv[6]; */
+       /* uint32_t ring_on_idle = atoi(argv[7]); */
+       /* uint32_t ring_on_active = atoi(argv[8]); */
+       /* uint32_t busy_trigger = atoi(argv[9]); */
+       /* char *forward_all = argv[10]; */
+       /* char *forward_busy = argv[11]; */
+       /* char *forward_noanswer = argv[12]; */
+       /* uint32_t noanswer_duration = atoi(argv[13]); */
+       /* char *channel_uuid = argv[14]; */
+       /* uint32_t call_id = atoi(argv[15]); */
+       /* uint32_t call_state = atoi(argv[16]); */
+
+       skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener);
+       if(listener) {
+           if(!strcmp(device_name, helper->listener->device_name) 
+                   && (device_instance == helper->listener->device_instance)
+                   && (line_instance == helper->line_instance)) {/* the calling line */
+                       helper->tech_pvt->caller_profile->dialplan = switch_core_strdup(helper->tech_pvt->caller_profile->pool, listener->profile->dialplan);
+                       helper->tech_pvt->caller_profile->context = switch_core_strdup(helper->tech_pvt->caller_profile->pool, listener->profile->context);
+                       send_dialed_number(listener, helper->tech_pvt->caller_profile->destination_number, line_instance, helper->tech_pvt->call_id);
+                       skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_PROCEED);
+                       skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
+           } else {
+                       send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
+                       skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_IN_USE_REMOTELY);
+                       send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, 10, 0xffff);
+                       send_display_prompt_status(listener, 0, SKINNY_DISP_IN_USE_REMOTE,
+                               line_instance, helper->tech_pvt->call_id);
+                       skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
+           }
+       }
+       return 0;
+}
+
 switch_status_t channel_on_routing(switch_core_session_t *session)
 {
        switch_channel_t *channel = switch_core_session_get_channel(session);
+       if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
+               skinny_action_t action;
+               private_t *tech_pvt = switch_core_session_get_private(session);
+               char *data = NULL;
+               listener_t *listener = NULL;
+               struct channel_on_routing_helper helper = {0};
+
+               if(switch_test_flag(tech_pvt, TFLAG_FORCE_ROUTE)) {
+                       action = SKINNY_ACTION_ROUTE;
+                       switch_clear_flag_locked(tech_pvt, TFLAG_FORCE_ROUTE);
+               } else {
+                       action = skinny_session_dest_match_pattern(session, &data);
+               }
+               switch(action) {
+                       case SKINNY_ACTION_ROUTE:
+                               skinny_profile_find_listener_by_device_name_and_instance(tech_pvt->profile,
+                                       switch_channel_get_variable(channel, "skinny_device_name"),
+                                       atoi(switch_channel_get_variable(channel, "skinny_device_instance")), &listener);
+                               if (listener) {
+                                       helper.tech_pvt = tech_pvt;
+                                       helper.listener = listener;
+                                       helper.line_instance = atoi(switch_channel_get_variable(channel, "skinny_line_instance"));
+                                       skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), channel_on_routing_callback, &helper);
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Could not find listener %s:%s for Channel %s\n",
+                                               switch_channel_get_variable(channel, "skinny_device_name"), switch_channel_get_variable(channel, "skinny_device_instance"),
+                                               switch_channel_get_name(channel));
+                               }
+                               break;
+                       case SKINNY_ACTION_WAIT:
+                               /* for now, wait forever */
+                               switch_channel_set_state(channel, CS_HIBERNATE);
+                               break;
+                       case SKINNY_ACTION_DROP:
+                       default:
+                               switch_channel_hangup(channel, SWITCH_CAUSE_UNALLOCATED_NUMBER);
+               }
+       }
 
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
 
@@ -591,7 +671,6 @@ switch_status_t channel_on_execute(switch_core_session_t *session)
 
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
 
-
        return SWITCH_STATUS_SUCCESS;
 }
 
@@ -651,11 +730,14 @@ int channel_on_hangup_callback(void *pArg, int argc, char **argv, char **columnN
                send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_OFF);
                switch (helper->cause) {
                        case SWITCH_CAUSE_UNALLOCATED_NUMBER:
+                           send_start_tone(listener, SKINNY_TONE_REORDER, 0, line_instance, call_id);
+                               skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
                                send_display_prompt_status(listener, 0, SKINNY_DISP_UNKNOWN_NUMBER, line_instance, call_id);
                                break;
                        case SWITCH_CAUSE_USER_BUSY:
+                           send_start_tone(listener, SKINNY_TONE_BUSYTONE, 0, line_instance, call_id);
                                send_display_prompt_status(listener, 0, SKINNY_DISP_BUSY, line_instance, call_id);
-                               break;
+                                       break;
                        case SWITCH_CAUSE_NORMAL_CLEARING:
                                send_clear_prompt_status(listener, line_instance, call_id);
                                break;
@@ -842,6 +924,20 @@ switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame
 
 switch_status_t channel_answer_channel(switch_core_session_t *session)
 {
+       switch_channel_t *channel = switch_core_session_get_channel(session);
+       private_t *tech_pvt = switch_core_session_get_private(session);
+       listener_t *listener = NULL;
+
+       skinny_profile_find_listener_by_device_name_and_instance(tech_pvt->profile,
+               switch_channel_get_variable(channel, "skinny_device_name"),
+               atoi(switch_channel_get_variable(channel, "skinny_device_instance")), &listener);
+       if (listener) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Bli!\n");
+               skinny_session_start_media(session, listener, atoi(switch_channel_get_variable(channel, "skinny_line_instance")));
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Unable to find listener to answer %s:%s\n",
+                       switch_channel_get_variable(channel, "skinny_device_name"), switch_channel_get_variable(channel, "skinny_device_instance"));
+       }
        return SWITCH_STATUS_SUCCESS;
 }
 
@@ -925,7 +1021,6 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi
        tech_pvt->caller_profile = caller_profile;
 
        switch_channel_set_flag(channel, CF_OUTBOUND);
-       switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
 
        if ((sql = switch_mprintf(
                        "INSERT INTO skinny_active_lines "
index 314e29ba7311ca99239763913c63fb887c0cc68d..90947e20c1297cb750efc4dae37e259f7ba80339 100644 (file)
@@ -146,8 +146,6 @@ typedef switch_status_t (*skinny_listener_callback_func_t) (listener_t *listener
 /*****************************************************************************/
 typedef enum {
     TFLAG_IO = (1 << 0),
-    TFLAG_INBOUND = (1 << 1),
-    TFLAG_OUTBOUND = (1 << 2),
     TFLAG_DTMF = (1 << 3),
     TFLAG_VOICE = (1 << 4),
     TFLAG_HANGUP = (1 << 5),
@@ -155,7 +153,8 @@ typedef enum {
     TFLAG_CODEC = (1 << 7),
 
     TFLAG_READING = (1 << 9),
-    TFLAG_WRITING = (1 << 10)
+    TFLAG_WRITING = (1 << 10),
+    TFLAG_FORCE_ROUTE = (1 << 11)
 } TFLAGS;
 
 typedef enum {
index f1479ba0dda1ef1db47f10657186e8e1e382eec8..aefbf7e31a2c0611200d3ffda740709124ed77af 100644 (file)
@@ -242,6 +242,15 @@ switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, s
        return SWITCH_STATUS_SUCCESS;
 }
 
+switch_status_t skinny_set_channel_variables(switch_channel_t *channel, listener_t *listener, uint32_t line_instance)
+{
+       switch_channel_set_variable(channel, "skinny_profile_name", listener->profile->name);
+       switch_channel_set_variable(channel, "skinny_device_name", listener->device_name);
+       switch_channel_set_variable_printf(channel, "skinny_device_instance", "%d", listener->device_instance);
+       switch_channel_set_variable_printf(channel, "skinny_line_instance", "%d", line_instance);
+       return SWITCH_STATUS_SUCCESS;
+}
+
 /*****************************************************************************/
 /*****************************************************************************/
 switch_status_t skinny_session_walk_lines(skinny_profile_t *profile, char *channel_uuid, switch_core_db_callback_func_t callback, void *data)
@@ -916,8 +925,9 @@ switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file
        ptr = (char *) reply;
 
        switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG,
-               "Sending %s (type=%x,length=%d).\n",
-               skinny_message_type2str(reply->type), reply->type, reply->length);
+               "Sending %s (type=%x,length=%d) to %s:%d.\n",
+               skinny_message_type2str(reply->type), reply->type, reply->length,
+               listener->device_name, listener->device_instance);
        switch_socket_send(listener->sock, ptr, &len);
 
        return SWITCH_STATUS_SUCCESS;
index 45bac962430fda7c904f7b6d5171732e3f7511d5..c9dcb4b81bbfb74660fd2cee775b6660fcec2575 100644 (file)
@@ -637,6 +637,7 @@ char* skinny_codec2string(enum skinny_codecs skinnycodec);
 switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req);
 
 switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, switch_event_types_t event_id, const char *subclass_name);
+switch_status_t skinny_set_channel_variables(switch_channel_t *channel, listener_t *listener, uint32_t line_instance);
 
 switch_status_t skinny_session_walk_lines(skinny_profile_t *profile, char *channel_uuid, switch_core_db_callback_func_t callback, void *data);
 
index 6ed1f36017f00bbfe84aba6fe6d25a2f777c3508..62ceffa446844059148e0589f24c8009fe0bd09d 100644 (file)
@@ -117,6 +117,7 @@ switch_status_t skinny_create_incoming_session(listener_t *listener, uint32_t *l
        snprintf(name, sizeof(name), "SKINNY/%s/%s:%d/%d", listener->profile->name, 
            listener->device_name, listener->device_instance, *line_instance_p);
        switch_channel_set_name(channel, name);
+       skinny_set_channel_variables(channel, listener, *line_instance_p);
 
        if (switch_core_session_thread_launch(nsession) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, 
@@ -163,6 +164,12 @@ switch_status_t skinny_create_incoming_session(listener_t *listener, uint32_t *l
        send_display_prompt_status(listener, 0, "\200\000",
                *line_instance_p, tech_pvt->call_id);
        send_activate_call_plane(listener, *line_instance_p);
+       if (switch_channel_get_state(channel) == CS_NEW) {
+               switch_channel_set_state(channel, CS_HIBERNATE);
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, 
+                   "Wow! this channel should be in CS_NEW state, but it is not!\n");
+       }
 
        goto done;
 error:
@@ -246,60 +253,10 @@ found:
 }
 
 
-struct skinny_session_process_dest_helper {
-       private_t *tech_pvt;
-       listener_t *listener;
-       uint32_t line_instance;
-};
-
-int skinny_session_process_dest_callback(void *pArg, int argc, char **argv, char **columnNames)
-{
-       struct skinny_session_process_dest_helper *helper = pArg;
-       listener_t *listener = NULL;
-
-       char *device_name = argv[0];
-       uint32_t device_instance = atoi(argv[1]);
-       /* uint32_t position = atoi(argv[2]); */
-       uint32_t line_instance = atoi(argv[3]);
-       /* char *label = argv[4]; */
-       /* char *value = argv[5]; */
-       /* char *caller_name = argv[6]; */
-       /* uint32_t ring_on_idle = atoi(argv[7]); */
-       /* uint32_t ring_on_active = atoi(argv[8]); */
-       /* uint32_t busy_trigger = atoi(argv[9]); */
-       /* char *forward_all = argv[10]; */
-       /* char *forward_busy = argv[11]; */
-       /* char *forward_noanswer = argv[12]; */
-       /* uint32_t noanswer_duration = atoi(argv[13]); */
-       /* char *channel_uuid = argv[14]; */
-       /* uint32_t call_id = atoi(argv[15]); */
-       /* uint32_t call_state = atoi(argv[16]); */
-
-       skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener);
-       if(listener) {
-           if(!strcmp(device_name, helper->listener->device_name) 
-                   && (device_instance == helper->listener->device_instance)
-                   && (line_instance == helper->line_instance)) {/* the calling line */
-               /* nothing */
-           } else {
-                       send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
-                       skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_IN_USE_REMOTELY);
-                       send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, 10, 0xffff);
-                       send_display_prompt_status(listener, 0, SKINNY_DISP_IN_USE_REMOTE,
-                               line_instance, helper->tech_pvt->call_id);
-                       skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
-           }
-       }
-       return 0;
-}
-
 switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace)
 {
-       skinny_action_t action;
        switch_channel_t *channel = NULL;
        private_t *tech_pvt = NULL;
-       char *data = NULL;
-       struct skinny_session_process_dest_helper helper = {0};
 
        switch_assert(session);
        switch_assert(listener);
@@ -333,34 +290,10 @@ switch_status_t skinny_session_process_dest(switch_core_session_t *session, list
        } else {
            tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool,
                dest);
+               switch_set_flag_locked(tech_pvt, TFLAG_FORCE_ROUTE);
        }
-       if(dest) {
-               action = SKINNY_ACTION_ROUTE;
-       } else {
-               action = skinny_session_dest_match_pattern(session, &data);
-       }
-       switch(action) {
-               case SKINNY_ACTION_ROUTE:
-                       tech_pvt->caller_profile->dialplan = switch_core_strdup(tech_pvt->caller_profile->pool, listener->profile->dialplan);
-                       tech_pvt->caller_profile->context = switch_core_strdup(tech_pvt->caller_profile->pool, listener->profile->context);
-                       send_dialed_number(listener, tech_pvt->caller_profile->destination_number, line_instance, tech_pvt->call_id);
-                       skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_PROCEED);
-                       skinny_session_send_call_info(session, listener, line_instance);
-
-                       skinny_session_start_media(session, listener, line_instance);
-                       
-                       helper.tech_pvt = tech_pvt;
-                       helper.listener = listener;
-                       helper.line_instance = line_instance;
-                       skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_process_dest_callback, &helper);
-                       break;
-               case SKINNY_ACTION_WAIT:
-                       /* for now, wait forever */
-                       break;
-               case SKINNY_ACTION_DROP:
-               default:
-                       switch_channel_hangup(channel, SWITCH_CAUSE_UNALLOCATED_NUMBER);
-       }
+       
+       switch_channel_set_state(channel, CS_ROUTING);
 
        return SWITCH_STATUS_SUCCESS;
 }
@@ -383,20 +316,28 @@ switch_status_t skinny_session_send_call_info(switch_core_session_t *session, li
 
        /* Calling party */
        if (zstr((caller_party_name = switch_channel_get_variable(channel, "effective_caller_id_name"))) &&
-               zstr((caller_party_name = switch_channel_get_variable(channel, "caller_id_name")))) {
+               zstr((caller_party_name = switch_channel_get_variable(channel, "caller_id_name"))) &&
+               zstr((caller_party_name = switch_channel_get_variable_partner(channel, "effective_caller_id_name"))) &&
+               zstr((caller_party_name = switch_channel_get_variable_partner(channel, "caller_id_name")))) {
                caller_party_name = SWITCH_DEFAULT_CLID_NAME;
        }
        if (zstr((caller_party_number = switch_channel_get_variable(channel, "effective_caller_id_number"))) &&
-               zstr((caller_party_number = switch_channel_get_variable(channel, "caller_id_number")))) {
+               zstr((caller_party_number = switch_channel_get_variable(channel, "caller_id_number"))) &&
+               zstr((caller_party_number = switch_channel_get_variable_partner(channel, "effective_caller_id_number"))) &&
+               zstr((caller_party_number = switch_channel_get_variable_partner(channel, "caller_id_number")))) {
                caller_party_number = "0000000000";
        }
        /* Called party */
        if (zstr((called_party_name = switch_channel_get_variable(channel, "effective_callee_id_name"))) &&
-               zstr((called_party_name = switch_channel_get_variable(channel, "callee_id_name")))) {
+               zstr((called_party_name = switch_channel_get_variable(channel, "callee_id_name"))) &&
+               zstr((called_party_name = switch_channel_get_variable_partner(channel, "effective_callee_id_name"))) &&
+               zstr((called_party_name = switch_channel_get_variable_partner(channel, "callee_id_name")))) {
                called_party_name = SWITCH_DEFAULT_CLID_NAME;
        }
        if (zstr((called_party_number = switch_channel_get_variable(channel, "effective_callee_id_number"))) &&
                zstr((called_party_number = switch_channel_get_variable(channel, "callee_id_number"))) &&
+               zstr((called_party_number = switch_channel_get_variable_partner(channel, "effective_callee_id_number"))) &&
+               zstr((called_party_number = switch_channel_get_variable_partner(channel, "callee_id_number"))) &&
                zstr((called_party_number = switch_channel_get_variable(channel, "destination_number")))) {
                called_party_number = "0000000000";
        }
@@ -615,6 +556,9 @@ switch_status_t skinny_session_answer(switch_core_session_t *session, listener_t
 
        skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_answer_callback, &helper);
 
+       if (switch_channel_get_state(channel) == CS_INIT) {
+               switch_channel_set_state(channel, CS_ROUTING);
+       }
        skinny_session_start_media(session, listener, line_instance);
 
        return SWITCH_STATUS_SUCCESS;
@@ -763,6 +707,8 @@ switch_status_t skinny_session_stop_media(switch_core_session_t *session, listen
        channel = switch_core_session_get_channel(session);
        tech_pvt = switch_core_session_get_private(session);
 
+       switch_clear_flag_locked(tech_pvt, TFLAG_IO);
+
        send_close_receive_channel(listener,
                tech_pvt->call_id, /* uint32_t conference_id, */
                tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
@@ -1565,10 +1511,12 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste
                        0 /* uint32_t g723_bitrate */
                        );
 
-               if (switch_channel_get_state(channel) == CS_NEW) {
-                       switch_channel_set_state(channel, CS_INIT);
-               }
+               switch_set_flag_locked(tech_pvt, TFLAG_IO);
                switch_channel_mark_answered(channel);
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+                       "Unable to find session for device %s:%d (call id=%d).\n", 
+                       listener->device_name, listener->device_instance, request->data.open_receive_channel_ack.pass_thru_party_id);
        }
 end:
        if(session) {
@@ -1819,7 +1767,8 @@ switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_
 switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request)
 {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
-               "Received %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);
+               "Received %s (type=%x,length=%d) from %s:%d.\n", skinny_message_type2str(request->type), request->type, request->length,
+               listener->device_name, listener->device_instance);
        if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
                        "Device should send a register message first.\n");
index f4651e184c37c89b1258254704e6951ca4710114..6aab6b99ff372d37bb29d07ca38b24c5beca0ee5 100644 (file)
@@ -36,6 +36,7 @@
 
 /* SESSION FUNCTIONS */
 switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *line_instance, switch_core_session_t **session);
+skinny_action_t skinny_session_dest_match_pattern(switch_core_session_t *session, char **data);
 switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace);
 switch_status_t skinny_session_send_call_info(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
 switch_call_cause_t skinny_ring_lines(private_t *tech_pvt);