root/src/ftdm_m3ua.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. release_request_id
  2. state_advance
  3. check_state
  4. parse_ss7_event
  5. FIO_CONFIGURE_FUNCTION
  6. FIO_CONFIGURE_SPAN_FUNCTION
  7. FIO_OPEN_FUNCTION
  8. FIO_CLOSE_FUNCTION
  9. FIO_WAIT_FUNCTION
  10. FIO_READ_FUNCTION
  11. FIO_WRITE_FUNCTION
  12. FIO_COMMAND_FUNCTION
  13. FIO_SPAN_POLL_EVENT_FUNCTION
  14. FIO_SPAN_NEXT_EVENT_FUNCTION
  15. FIO_SPAN_DESTROY_FUNCTION
  16. FIO_CHANNEL_DESTROY_FUNCTION
  17. FIO_GET_ALARMS_FUNCTION
  18. m3ua_init
  19. m3ua_destroy
  20. m3ua_run
  21. m3ua_start

   1 /*
   2  *  ftdm_m3ua.c
   3  *  freetdm
   4  *
   5  *  Created by Shane Burrell on 4/3/08.
   6  *  Copyright 2008 Shane Burrell. All rights reserved.
   7  *
   8  * 
   9  * Copyright (c) 2007, Anthony Minessale II, Nenad Corbic * 
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 
  15  * * Redistributions of source code must retain the above copyright
  16  * notice, this list of conditions and the following disclaimer.
  17  * 
  18  * * Redistributions in binary form must reproduce the above copyright
  19  * notice, this list of conditions and the following disclaimer in the
  20  * documentation and/or other materials provided with the distribution.
  21  * 
  22  * * Neither the name of the original author; nor the names of any contributors
  23  * may be used to endorse or promote products derived from this software
  24  * without specific prior written permission.
  25  * 
  26  * 
  27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  30  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  31  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  32  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  33  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  34  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  35  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  36  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38  */
  39 
  40 
  41 #include "freetdm.h"
  42 #include "m3ua_client.h"
  43 #include "ftdm_m3ua.h"
  44 
  45 #define MAX_REQ_ID MAX_PENDING_CALLS
  46 typedef uint16_t m3ua_request_id_t;
  47 
  48 typedef enum {
  49         BST_FREE,
  50         BST_WAITING,
  51         BST_READY,
  52         BST_FAIL
  53 } m3ua_request_status_t;
  54 
  55 typedef struct {
  56         m3ua_request_status_t status;
  57         m3uac_event_t event;
  58         ftdm_span_t *span;
  59         ftdm_channel_t *ftdmchan;
  60 } m3ua_request_t;
  61 
  62 
  63 struct general_config {
  64         uint32_t region;
  65 };
  66 typedef struct general_config general_config_t;
  67 
  68 
  69 struct m3ua_channel_profile {
  70         char name[80];
  71         int cust_span;
  72         unsigned char opc[3];
  73         unsigned char dpc[3];
  74         int local_ip[4];
  75         int local_port;
  76         int remote_ip[4];
  77         int remote_port;
  78         int m3ua_mode;
  79 };
  80 typedef struct m3ua_channel_profile m3ua_channel_profile_t;
  81 
  82 static struct {
  83         ftdm_hash_t *profile_hash;
  84         general_config_t general_config;
  85 } globals;
  86 
  87 struct m3ua_span_data {
  88         uint32_t boardno;
  89         uint32_t flags;
  90 };
  91 typedef struct m3ua_span_data m3ua_span_data_t;
  92 
  93 struct m3ua_chan_data {
  94         ftdm_buffer_t *digit_buffer;
  95         ftdm_mutex_t *digit_mutex;
  96         ftdm_size_t dtmf_len;
  97         uint32_t flags;
  98         uint32_t hdlc_bytes;
  99 };
 100 typedef struct m3ua_chan_data m3ua_chan_data_t;
 101 
 102 static ftdm_mutex_t *request_mutex = NULL;
 103 static ftdm_mutex_t *signal_mutex = NULL;
 104 
 105 static uint8_t req_map[MAX_REQ_ID+1] = { 0 };
 106 
 107 static void release_request_id(m3ua_request_id_t r)
 108 {
 109         ftdm_mutex_lock(request_mutex);
 110         req_map[r] = 0;
 111         ftdm_mutex_unlock(request_mutex);
 112 }
 113 
 114 /*static m3ua_request_id_t next_request_id(void)
 115 {
 116         m3ua_request_id_t r = 0;
 117         int ok = 0;
 118         
 119         while(!ok) {
 120                 ftdm_mutex_lock(request_mutex);
 121                 for (r = 1; r <= MAX_REQ_ID; r++) {
 122                         if (!req_map[r]) {
 123                                 ok = 1;
 124                                 req_map[r] = 1;
 125                                 break;
 126                         }
 127                 }
 128                 ftdm_mutex_unlock(request_mutex);
 129                 if (!ok) {
 130                         ftdm_sleep(5);
 131                 }
 132         }
 133         return r;
 134 }
 135 */
 136 
 137 static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
 138 {
 139 
 140         m3ua_data_t *m3ua_data = ftdmchan->span->signal_data;
 141         m3uac_connection_t *mcon = &m3ua_data->mcon;
 142         ftdm_sigmsg_t sig;
 143         ftdm_status_t status;
 144 
 145         ftdm_log(FTDM_LOG_DEBUG, "%d:%d STATE [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state));
 146         
 147         memset(&sig, 0, sizeof(sig));
 148         sig.chan_id = ftdmchan->chan_id;
 149         sig.span_id = ftdmchan->span_id;
 150         sig.channel = ftdmchan;
 151 
 152         switch (ftdmchan->state) {
 153         case FTDM_CHANNEL_STATE_DOWN:
 154                 {
 155                         if (ftdmchan->extra_id) {
 156                                 release_request_id((m3ua_request_id_t)ftdmchan->extra_id);
 157                                 ftdmchan->extra_id = 0;
 158                         }
 159                         ftdm_channel_done(ftdmchan);                    
 160                 }
 161                 break;
 162         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 163         case FTDM_CHANNEL_STATE_PROGRESS:
 164                 {
 165                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 166                                 sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
 167                                 if ((status = m3ua_data->signal_cb(&sig) != FTDM_SUCCESS)) {
 168                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
 169                                 }
 170                         } else {
 171                                 m3uac_exec_command(mcon,
 172                                                                    ftdmchan->physical_span_id-1,
 173                                                                    ftdmchan->physical_chan_id-1,                                                                   
 174                                                                    0,
 175                                                                    SIGBOOST_EVENT_CALL_START_ACK,
 176                                                                    0);
 177                         }
 178                 }
 179                 break;
 180         case FTDM_CHANNEL_STATE_RING:
 181                 {
 182                         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 183                                 sig.event_id = FTDM_SIGEVENT_START;
 184                                 if ((status = m3ua_data->signal_cb(&sig) != FTDM_SUCCESS)) {
 185                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
 186                                 }
 187                         }
 188 
 189                 }
 190                 break;
 191         case FTDM_CHANNEL_STATE_RESTART:
 192                 {
 193                         if (ftdmchan->last_state != FTDM_CHANNEL_STATE_HANGUP && ftdmchan->last_state != FTDM_CHANNEL_STATE_DOWN) {
 194                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
 195                         } else {
 196                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 197                         }
 198                 }
 199                 break;
 200         case FTDM_CHANNEL_STATE_UP:
 201                 {
 202                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 203                                 sig.event_id = FTDM_SIGEVENT_UP;
 204                                 if ((status = m3ua_data->signal_cb(&sig) != FTDM_SUCCESS)) {
 205                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
 206                                 }
 207                         } else {
 208                                 if (!(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MEDIA))) {
 209                                         m3uac_exec_command(mcon,
 210                                                                            ftdmchan->physical_span_id-1,
 211                                                                            ftdmchan->physical_chan_id-1,                                                                   
 212                                                                            0,
 213                                                                            SIGBOOST_EVENT_CALL_START_ACK,
 214                                                                            0);
 215                                 }
 216                                 
 217                                 m3uac_exec_command(mcon,
 218                                                                    ftdmchan->physical_span_id-1,
 219                                                                    ftdmchan->physical_chan_id-1,                                                                   
 220                                                                    0,
 221                                                                    SIGBOOST_EVENT_CALL_ANSWERED,
 222                                                                    0);
 223                         }
 224                 }
 225                 break;
 226         case FTDM_CHANNEL_STATE_DIALING:
 227                 {
 228                 }
 229                 break;
 230         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 231                 {
 232                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 233                 }
 234                 break;
 235         case FTDM_CHANNEL_STATE_HANGUP:
 236                 {
 237                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_ANSWERED) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MEDIA)) {
 238                                 m3uac_exec_command(mcon,
 239                                                                    ftdmchan->physical_span_id-1,
 240                                                                    ftdmchan->physical_chan_id-1,
 241                                                                    0,
 242                                                                    SIGBOOST_EVENT_CALL_STOPPED,
 243                                                                    ftdmchan->caller_data.hangup_cause);
 244                         } else {
 245                                 m3uac_exec_command(mcon,
 246                                                                    ftdmchan->physical_span_id-1,
 247                                                                    ftdmchan->physical_chan_id-1,                                                                   
 248                                                                    0,
 249                                                                    SIGBOOST_EVENT_CALL_START_NACK,
 250                                                                    ftdmchan->caller_data.hangup_cause);
 251                         }                       
 252                 }
 253                 break;
 254         case FTDM_CHANNEL_STATE_CANCEL:
 255                 {
 256                         sig.event_id = FTDM_SIGEVENT_STOP;
 257                         status = m3ua_data->signal_cb(&sig);
 258                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 259                         m3uac_exec_command(mcon,
 260                                                            ftdmchan->physical_span_id-1,
 261                                                            ftdmchan->physical_chan_id-1,
 262                                                            0,
 263                                                            SIGBOOST_EVENT_CALL_START_NACK_ACK,
 264                                                            0);
 265                 }
 266                 break;
 267         case FTDM_CHANNEL_STATE_TERMINATING:
 268                 {
 269                         sig.event_id = FTDM_SIGEVENT_STOP;
 270                         status = m3ua_data->signal_cb(&sig);
 271                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 272                         m3uac_exec_command(mcon,
 273                                                            ftdmchan->physical_span_id-1,
 274                                                            ftdmchan->physical_chan_id-1,
 275                                                            0,
 276                                                            SIGBOOST_EVENT_CALL_STOPPED_ACK,
 277                                                            0);
 278                 }
 279                 break;
 280         default:
 281                 break;
 282         }
 283 }
 284 
 285 
 286 static __inline__ void check_state(ftdm_span_t *span)
 287 {
 288     if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
 289         uint32_t j;
 290         ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
 291         for(j = 1; j <= span->chan_count; j++) {
 292             if (ftdm_test_flag((&span->channels[j]), FTDM_CHANNEL_STATE_CHANGE)) {
 293                 ftdm_clear_flag_locked((&span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
 294                 state_advance(&span->channels[j]);
 295                 ftdm_channel_complete_state(&span->channels[j]);
 296             }
 297         }
 298     }
 299 }
 300 
 301 
 302 static int parse_ss7_event(ftdm_span_t *span, m3uac_connection_t *mcon, m3uac_event_t *event)
 303 {
 304         ftdm_mutex_lock(signal_mutex);
 305         
 306         if (!ftdm_running()) {
 307                 ftdm_log(FTDM_LOG_WARNING, "System is shutting down.\n");
 308                 goto end;
 309         }
 310 
 311 
 312         if (ftdm_test_flag(span, FTDM_SPAN_SUSPENDED) && 
 313                 event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART_ACK && event->event_id != SIGBOOST_EVENT_HEARTBEAT) {
 314 
 315                 ftdm_log(FTDM_LOG_WARNING,
 316                                 "INVALID EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n",
 317                                 m3uac_event_id_name(event->event_id),
 318                                 event->event_id,
 319                                 event->span+1,
 320                                 event->chan+1,
 321                                 event->release_cause,
 322                                 event->call_setup_id,
 323                                 event->fseqno,
 324                                 (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
 325                                 (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")
 326                                 );
 327                 
 328                 goto end;
 329         }
 330 
 331 
 332         ftdm_log(FTDM_LOG_DEBUG,
 333                         "RX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n",
 334                            m3uac_event_id_name(event->event_id),
 335                            event->event_id,
 336                            event->span+1,
 337                            event->chan+1,
 338                            event->release_cause,
 339                            event->call_setup_id,
 340                            event->fseqno,
 341                            (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
 342                            (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")
 343                            );
 344 
 345 
 346         
 347     switch(event->event_id) {
 348 
 349     case SIGBOOST_EVENT_CALL_START:
 350                 //handle_call_start(span, mcon, event);
 351                 break;
 352     case SIGBOOST_EVENT_CALL_STOPPED:
 353                 //handle_call_stop(span, mcon, event);
 354                 break;
 355     case SIGBOOST_EVENT_CALL_START_ACK:
 356                 //handle_call_start_ack(mcon, event);
 357                 break;
 358     case SIGBOOST_EVENT_CALL_START_NACK:
 359                 //handle_call_start_nack(span, mcon, event);
 360                 break;
 361     case SIGBOOST_EVENT_CALL_ANSWERED:
 362                 //handle_call_answer(span, mcon, event);
 363                 break;
 364     case SIGBOOST_EVENT_HEARTBEAT:
 365                 //handle_heartbeat(mcon, event);
 366                 break;
 367     case SIGBOOST_EVENT_CALL_STOPPED_ACK:
 368     case SIGBOOST_EVENT_CALL_START_NACK_ACK:
 369                 //handle_call_done(span, mcon, event);
 370                 break;
 371     case SIGBOOST_EVENT_INSERT_CHECK_LOOP:
 372                 //handle_call_loop_start(event);
 373                 break;
 374     case SIGBOOST_EVENT_REMOVE_CHECK_LOOP:
 375                 //handle_call_stop(event);
 376                 break;
 377     case SIGBOOST_EVENT_SYSTEM_RESTART_ACK:
 378                 //handle_restart_ack(mcon, span, event);
 379                 break;
 380     case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE:
 381                 //handle_gap_abate(event);
 382                 break;
 383     default:
 384                 ftdm_log(FTDM_LOG_WARNING, "No handler implemented for [%s]\n", m3uac_event_id_name(event->event_id));
 385                 break;
 386     }
 387 
 388  end:
 389 
 390         ftdm_mutex_unlock(signal_mutex);
 391 
 392         return 0;
 393 }
 394 
 395 static FIO_CONFIGURE_FUNCTION(m3ua_configure)
 396 {
 397         m3ua_channel_profile_t *profile = NULL;
 398 
 399         int ok = 1;
 400 
 401         if (!(profile = (m3ua_channel_profile_t *) hashtable_search(globals.profile_hash, (char *)category))) {
 402                 profile = ftdm_malloc(sizeof(*profile));
 403                 memset(profile, 0, sizeof(*profile));
 404                 ftdm_set_string(profile->name, category);
 405                 hashtable_insert(globals.profile_hash, (void *)profile->name, profile);
 406                 ftdm_log(FTDM_LOG_INFO, "creating profile [%s]\n", category);
 407         }
 408 
 409 //      ftdm_set_string(m3ua_data->mcon. cfg.local_ip, local_ip);
 410         if (!strcasecmp(var, "local_sctp_port")) {
 411                 profile->local_port = 30000 ;
 412                 profile->remote_port = 30000;
 413                 profile->cust_span++;
 414         } 
 415         ok = 1;
 416         
 417 
 418         if (ok) {
 419                 ftdm_log(FTDM_LOG_INFO, "setting param [%s]=[%s] for profile [%s]\n", var, val, category);
 420         } else {
 421                 ftdm_log(FTDM_LOG_ERROR, "unknown param [%s]\n", var);
 422         }
 423 
 424         return FTDM_SUCCESS;
 425 }
 426 
 427 static FIO_CONFIGURE_SPAN_FUNCTION(m3ua_configure_span)
 428 {
 429 
 430         return FTDM_FAIL;
 431 }
 432 
 433 static FIO_OPEN_FUNCTION(m3ua_open) 
 434 {
 435         
 436         return FTDM_FAIL;
 437 }
 438 
 439 static FIO_CLOSE_FUNCTION(m3ua_close)
 440 {
 441         
 442         return FTDM_FAIL;
 443 }
 444 
 445 /*static FIO_SET_INTERVAL_FUNCTION(m3ua_set_interval)
 446 {
 447         
 448         return 0;
 449 }*/
 450 
 451 static FIO_WAIT_FUNCTION(m3ua_wait)
 452 {
 453         
 454         return FTDM_FAIL;
 455 }
 456 
 457 static FIO_READ_FUNCTION(m3ua_read)
 458 {
 459         
 460         return FTDM_FAIL;
 461 }
 462 
 463 static FIO_WRITE_FUNCTION(m3ua_write)
 464 {
 465         
 466         return FTDM_FAIL;
 467 }
 468 
 469 static FIO_COMMAND_FUNCTION(m3ua_command)
 470 {
 471         return FTDM_FAIL;
 472 }
 473 
 474 static FIO_SPAN_POLL_EVENT_FUNCTION(m3ua_poll_event)
 475 {
 476         return FTDM_FAIL;
 477 }
 478 
 479 static FIO_SPAN_NEXT_EVENT_FUNCTION(m3ua_next_event)
 480 {
 481         return FTDM_FAIL;
 482 }
 483 
 484 
 485 static FIO_SPAN_DESTROY_FUNCTION(m3ua_span_destroy)
 486 {
 487         m3ua_span_data_t *span_data = (m3ua_span_data_t *) span->mod_data;
 488         
 489         if (span_data) {
 490                 ftdm_safe_free(span_data);
 491         }
 492         
 493         return FTDM_SUCCESS;
 494 }
 495 static FIO_CHANNEL_DESTROY_FUNCTION(m3ua_channel_destroy)
 496 {
 497         m3ua_chan_data_t *chan_data = (m3ua_chan_data_t *) ftdmchan->mod_data;
 498         m3ua_span_data_t *span_data = (m3ua_span_data_t *) ftdmchan->span->mod_data;
 499         
 500         if (!chan_data) {
 501                 return FTDM_FAIL;
 502         }
 503 
 504         
 505                 
 506 
 507 
 508 
 509         ftdm_mutex_destroy(&chan_data->digit_mutex);
 510         ftdm_buffer_destroy(&chan_data->digit_buffer);
 511 
 512 
 513         ftdm_safe_free(chan_data);
 514         
 515         if (span_data) {
 516                 ftdm_safe_free(span_data);
 517         }
 518         
 519                         
 520         return FTDM_SUCCESS;
 521 }
 522 
 523 
 524 
 525 static FIO_GET_ALARMS_FUNCTION(m3ua_get_alarms)
 526 {
 527         return FTDM_FAIL;
 528 }
 529 
 530 static ftdm_io_interface_t m3ua_interface;
 531 
 532 ftdm_status_t m3ua_init(ftdm_io_interface_t **zint)
 533 {
 534         assert(zint != NULL);
 535         memset(&m3ua_interface, 0, sizeof(m3ua_interface));
 536 
 537         m3ua_interface.name = "m3ua";
 538         m3ua_interface.configure =  m3ua_configure;
 539         m3ua_interface.configure_span =  m3ua_configure_span;
 540         m3ua_interface.open = m3ua_open;
 541         m3ua_interface.close = m3ua_close;
 542         m3ua_interface.wait = m3ua_wait;
 543         m3ua_interface.read = m3ua_read;
 544         m3ua_interface.write = m3ua_write;
 545         m3ua_interface.command = m3ua_command;
 546         m3ua_interface.poll_event = m3ua_poll_event;
 547         m3ua_interface.next_event = m3ua_next_event;
 548         m3ua_interface.channel_destroy = m3ua_channel_destroy;
 549         m3ua_interface.span_destroy = m3ua_span_destroy;
 550         m3ua_interface.get_alarms = m3ua_get_alarms;
 551         *zint = &m3ua_interface;
 552 
 553         return FTDM_FAIL;
 554 }
 555 
 556 ftdm_status_t m3ua_destroy(void)
 557 {
 558         return FTDM_FAIL;
 559 }
 560 
 561 
 562 static void *m3ua_run(ftdm_thread_t *me, void *obj)
 563 {
 564     ftdm_span_t *span = (ftdm_span_t *) obj;
 565     m3ua_data_t *m3ua_data = span->signal_data;
 566         m3uac_connection_t *mcon, *pcon;
 567         uint32_t ms = 10, too_long = 60000;
 568                 
 569 
 570         m3ua_data->pcon = m3ua_data->mcon;
 571 
 572         if (m3uac_connection_open(&m3ua_data->mcon,
 573                                                           m3ua_data->mcon.cfg.local_ip,
 574                                                           m3ua_data->mcon.cfg.local_port,
 575                                                           m3ua_data->mcon.cfg.remote_ip,
 576                                                           m3ua_data->mcon.cfg.remote_port) < 0) {
 577                 ftdm_log(FTDM_LOG_DEBUG, "Error: Opening MCON Socket [%d] %s\n", m3ua_data->mcon.socket, strerror(errno));
 578                 goto end;
 579     }
 580 
 581         if (m3uac_connection_open(&m3ua_data->pcon,
 582                                                           m3ua_data->pcon.cfg.local_ip,
 583                                                           ++m3ua_data->pcon.cfg.local_port,
 584                                                           m3ua_data->pcon.cfg.remote_ip,
 585                                                           m3ua_data->pcon.cfg.remote_port) < 0) {
 586                 ftdm_log(FTDM_LOG_DEBUG, "Error: Opening PCON Socket [%d] %s\n", m3ua_data->pcon.socket, strerror(errno));
 587                 goto end;
 588     }
 589         
 590         mcon = &m3ua_data->mcon;
 591         pcon = &m3ua_data->pcon;
 592 
 593         top:
 594 
 595         //init_outgoing_array();                
 596 
 597         m3uac_exec_command(mcon,
 598                                            0,
 599                                            0,
 600                                            -1,
 601                                            SIGBOOST_EVENT_SYSTEM_RESTART,
 602                                            0);
 603         
 604         while (ftdm_test_flag(m3ua_data, FTDM_M3UA_RUNNING)) {
 605                 fd_set rfds, efds;
 606                 struct timeval tv = { 0, ms * 1000 };
 607                 int max, activity, i = 0;
 608                 m3uac_event_t *event = NULL;
 609                 
 610                 if (!ftdm_running()) {
 611                         m3uac_exec_command(mcon,
 612                                                            0,
 613                                                            0,
 614                                                            -1,
 615                                                            SIGBOOST_EVENT_SYSTEM_RESTART,
 616                                                            0);
 617                         break;
 618                 }
 619 
 620                 FD_ZERO(&rfds);
 621                 FD_ZERO(&efds);
 622                 FD_SET(mcon->socket, &rfds);
 623                 FD_SET(mcon->socket, &efds);
 624                 FD_SET(pcon->socket, &rfds);
 625                 FD_SET(pcon->socket, &efds);
 626 
 627                 max = ((pcon->socket > mcon->socket) ? pcon->socket : mcon->socket) + 1;
 628                 
 629                 if ((activity = select(max, &rfds, NULL, &efds, &tv)) < 0) {
 630                         goto error;
 631                 }
 632                 
 633                 if (activity) {
 634                         if (FD_ISSET(pcon->socket, &efds) || FD_ISSET(mcon->socket, &efds)) {
 635                                 goto error;
 636                         }
 637 
 638                         if (FD_ISSET(pcon->socket, &rfds)) {
 639                                 if ((event = m3uac_connection_readp(pcon, i))) {
 640                                         parse_ss7_event(span, mcon, event);
 641                                 } else goto top;
 642                         }
 643 
 644                         if (FD_ISSET(mcon->socket, &rfds)) {
 645                                 if ((event = m3uac_connection_read(mcon, i))) {
 646                                         parse_ss7_event(span, mcon, event);
 647                                 } else goto top;
 648                         }
 649                 }
 650                 
 651                 check_state(span);
 652                 mcon->hb_elapsed += ms;
 653                 
 654                 if (mcon->hb_elapsed >= too_long && (mcon->up || !ftdm_test_flag(span, FTDM_SPAN_SUSPENDED))) {
 655                         ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART);
 656                         ftdm_set_flag_locked(span, FTDM_SPAN_SUSPENDED);
 657                         mcon->up = 0;
 658                         ftdm_log(FTDM_LOG_CRIT, "Lost Heartbeat!\n");
 659                 }
 660 
 661         }
 662 
 663         goto end;
 664 
 665  error:
 666         ftdm_log(FTDM_LOG_CRIT, "Socket Error!\n");
 667 
 668  end:
 669 
 670         m3uac_connection_close(&m3ua_data->mcon);
 671         m3uac_connection_close(&m3ua_data->pcon);
 672 
 673         ftdm_clear_flag(m3ua_data, FTDM_M3UA_RUNNING);
 674 
 675         ftdm_log(FTDM_LOG_DEBUG, "M3UA thread ended.\n");
 676         return NULL;
 677 }
 678 ftdm_status_t m3ua_start(ftdm_span_t *span)
 679 {
 680         m3ua_data_t *m3ua_data = span->signal_data;
 681         ftdm_set_flag(m3ua_data, FTDM_M3UA_RUNNING);
 682         return ftdm_thread_create_detached(m3ua_run, span);
 683 }
 684 
 685 /* For Emacs:
 686  * Local Variables:
 687  * mode:c
 688  * indent-tabs-mode:t
 689  * tab-width:4
 690  * c-basic-offset:4
 691  * End:
 692 */

/* [<][>][^][v][top][bottom][index][help] */