]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm/libpri: Add support to change status of an individual channel or multiple...
authorMarc Olivier Chouinard <mochouinard@moctel.com>
Sat, 6 Aug 2011 02:50:58 +0000 (22:50 -0400)
committerMarc Olivier Chouinard <mochouinard@moctel.com>
Sat, 6 Aug 2011 02:50:58 +0000 (22:50 -0400)
NOTE: There is bugs in libpri, even latest 1.4.12 as of this writing if you use NI2.   So rightnow it only work in DMS100/ATT mode.  Email me to get the NI2 patch (really stupid error).
NOTE2: The way libpri is build doesn't allow to do advance feature with the SERVICE feature, so if you put an channel out of service, and the far end send an restart, it will be bring back in service.  Lot of changes in libpri is required to allow this.  I need to figure out what would be the best steps to take since I don't have commit access to libpri release.
NOTE3: You need to enable this feature by setting service_message_support to true on the span

libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h

index 7a8e74fd7c07c90030a7af6dac6b3dd06e492cd2..a379aeda9c9ffec54b19e192460c53c891b3679f 100644 (file)
@@ -204,6 +204,32 @@ static int parse_debug(const char *in, uint32_t *flags)
        return res;
 }
 
+/**
+ * \brief Parses a change status string to flags
+ * \param in change status string to parse for
+ * \return Flags
+ */
+static int parse_change_status(const char *in)
+{
+       int flags = 0;
+       if (!in) {
+               return 0;
+       }
+
+       if (strstr(in, "in_service") || strstr(in, "in")) {
+               flags = SERVICE_CHANGE_STATUS_INSERVICE;
+       }
+       if (strstr(in, "maintenance") || strstr(in, "maint")) {
+               flags = SERVICE_CHANGE_STATUS_MAINTENANCE;
+       }
+       if (strstr(in, "out_of_service") || strstr(in, "out")) {
+               flags = SERVICE_CHANGE_STATUS_OUTOFSERVICE;
+       }
+
+
+       return flags;
+}
+
 static int print_debug(uint32_t flags, char *tmp, const int size)
 {
        int offset = 0;
@@ -240,6 +266,9 @@ static ftdm_io_interface_t ftdm_libpri_interface;
 static const char *ftdm_libpri_usage =
        "Usage:\n"
        "libpri kill <span>\n"
+       "libpri reset <span>\n"
+       "libpri restart <span> <channel/all>\n"
+       "libpri maintenance <span> <channel/all> <in/maint/out>\n"
        "libpri debug <span> [all|none|flag,...flagN]\n"
        "\n"
        "Possible debug flags:\n"
@@ -339,8 +368,78 @@ static FIO_API_FUNCTION(ftdm_libpri_api)
                                goto done;
                        }
                }
+               if (!strcasecmp(argv[0], "reset")) {
+                       ftdm_span_t *span = NULL;
+                       if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) {
+                               ftdm_libpri_data_t *isdn_data = span->signal_data;
+                               if (span->start != ftdm_libpri_start) {
+                                       stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
+                                       goto done;
+                               }
+
+                               pri_restart(isdn_data->spri.pri);
+                               stream->write_function(stream, "%s: +OK reset.\n", __FILE__);
+                               goto done;
+                       } else {
+                               stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
+                               goto done;
+                       }
+               }
+               if (!strcasecmp(argv[0], "restart") && argc == 3) {
+                       ftdm_span_t *span = NULL;
+                       if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) {
+                               ftdm_libpri_data_t *isdn_data = span->signal_data;
+                               if (span->start != ftdm_libpri_start) {
+                                       stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
+                                       goto done;
+                               }
+                               if (!strcasecmp(argv[2], "all")) {
+                                       int j;
+                                       for(j = 1; j <= span->chan_count; j++) {
+                                               pri_reset(isdn_data->spri.pri, j);
+                                               ftdm_sleep(50);
+                                       }
+                               } else {
+                                       pri_reset(isdn_data->spri.pri, atoi(argv[2]));
+                               }
+                               stream->write_function(stream, "%s: +OK restart set.\n", __FILE__);
+                               goto done;
+                       } else {
+                               stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
+                               goto done;
+                       }
+               }
+               if (!strcasecmp(argv[0], "maintenance") && argc > 3) {
+                       ftdm_span_t *span = NULL;
+                       if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) {
+                               ftdm_libpri_data_t *isdn_data = span->signal_data;
+                               if (span->start != ftdm_libpri_start) {
+                                       stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
+                                       goto done;
+                               }
+                               if (!isdn_data->service_message_support) {
+                                       stream->write_function(stream, "%s: -ERR service message support is disabled\n", __FILE__);
+                                       goto done;
+                               }
+                               if (!strcasecmp(argv[2], "all")) {
+                                       int j;
+                                       for(j = 1; j <= span->chan_count; j++) {
+                                               pri_maintenance_service(isdn_data->spri.pri, atoi(argv[1]), j, parse_change_status(argv[3]));
+                                               ftdm_sleep(50);
+                                       }
+                               } else {
+                                       pri_maintenance_service(isdn_data->spri.pri, atoi(argv[1]), atoi(argv[2]), parse_change_status(argv[3]));
+                               }
+                               stream->write_function(stream, "%s: +OK change status set.\n", __FILE__);
+                               goto done;
+                       } else {
+                               stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
+                               goto done;
+                       }
+               }
 
        }
+
        stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__);
 
 done:
@@ -1780,6 +1879,10 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
                        pri_facility_enable(isdn_data->spri.pri);
                }
 #endif
+               /* Support the different switch of service status */
+               if (isdn_data->service_message_support) {
+                       pri_set_service_message_support(isdn_data->spri.pri, 1 /* True */);
+               }
 
                if (res == 0) {
                        LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_ANY, on_anything);
@@ -2159,6 +2262,11 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
                                isdn_data->debug_mask = 0;
                        }
                }
+               else if (!strcasecmp(var, "service_message_support")) {
+                       if (ftdm_true(val)) {
+                               isdn_data->service_message_support = 1;
+                       }
+               }
                else {
                        ftdm_log(FTDM_LOG_ERROR, "Unknown parameter '%s', aborting configuration\n", var);
                        snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
index 4ec15c7b698b90554e21e04870741744b50f526f..27b1763fecd981fbfb3d02a32a0c6d29a7cda272 100644 (file)
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+typedef enum {
+        SERVICE_CHANGE_STATUS_INSERVICE = 0,
+        SERVICE_CHANGE_STATUS_MAINTENANCE = 1,
+        SERVICE_CHANGE_STATUS_OUTOFSERVICE = 2
+} service_change_status_t;     
 
 #ifndef FTMOD_LIBPRI_H
 #define FTMOD_LIBPRI_H
@@ -69,6 +74,7 @@ struct ftdm_libpri_data {
        int overlap;            /*!< Overlap dial flags */
        unsigned int layer1;
        unsigned int ton;
+       unsigned int service_message_support;
 
        lpwrap_pri_t spri;
 };