]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
WIP
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 13 Jun 2007 03:37:55 +0000 (03:37 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 13 Jun 2007 03:37:55 +0000 (03:37 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@251 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/openzap/mod_openzap/mod_openzap.c
libs/openzap/src/include/openzap.h
libs/openzap/src/priserver.c
libs/openzap/src/sangoma_pri.c
libs/openzap/src/testisdn.c
libs/openzap/src/zap_io.c
libs/openzap/src/zap_isdn.c

index 070ea50e5dc6c525b0d5cded110818078f76bba4..e4793fe8071aa0d0409feef39e94f24029f4061d 100644 (file)
@@ -316,6 +316,13 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
                        }
                }
                break;
+       case ZAP_CHAN_TYPE_B:
+               {
+                       if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
+                               zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_HANGUP);
+                       }
+               }
+               break;
        default: 
                {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled type for channel %s\n", switch_channel_get_name(channel));
@@ -536,7 +543,27 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
 
 static switch_status_t channel_receive_message_b(switch_core_session_t *session, switch_core_session_message_t *msg)
 {
-       return SWITCH_STATUS_FALSE;
+       switch_channel_t *channel;
+       private_t *tech_pvt;
+
+       channel = switch_core_session_get_channel(session);
+       assert(channel != NULL);
+                       
+       tech_pvt = (private_t *) switch_core_session_get_private(session);
+       assert(tech_pvt != NULL);
+       
+       switch (msg->message_id) {
+       case SWITCH_MESSAGE_INDICATE_PROGRESS:
+       case SWITCH_MESSAGE_INDICATE_ANSWER:
+               if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
+                       zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP);
+               }
+               break;
+       default:
+               break;
+       }
+
+       return SWITCH_STATUS_SUCCESS;
 }
 
 static switch_status_t channel_receive_message_fxo(switch_core_session_t *session, switch_core_session_message_t *msg)
@@ -913,7 +940,46 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
        return status;
 }
 
-static ZIO_SIGNAL_CB_FUNCTION(on_zap_signal)
+static ZIO_SIGNAL_CB_FUNCTION(on_isdn_signal)
+{
+       switch_core_session_t *session = NULL;
+       switch_channel_t *channel = NULL;
+       zap_status_t status;
+
+       zap_log(ZAP_LOG_DEBUG, "got ISDN sig [%s]\n", zap_signal_event2str(sigmsg->event_id));
+
+    switch(sigmsg->event_id) {
+    case ZAP_SIGEVENT_START:
+               {
+                       return zap_channel_from_event(sigmsg, &session);
+               }
+               break;
+    case ZAP_SIGEVENT_STOP:
+               {
+                       while((session = zap_channel_get_session(sigmsg->channel, 0))) {
+                               zap_channel_clear_token(sigmsg->channel, 0);
+                               channel = switch_core_session_get_channel(session);
+                               switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+                               switch_core_session_rwunlock(session);
+                       }
+               }
+               break;
+    case ZAP_SIGEVENT_UP:
+               {
+                       if ((session = zap_channel_get_session(sigmsg->channel, 0))) {
+                               channel = switch_core_session_get_channel(session);
+                               switch_channel_mark_answered(channel);
+                               switch_core_session_rwunlock(session);
+                       }
+               }
+               break;
+       }
+
+       return ZAP_SUCCESS;
+}
+
+
+static ZIO_SIGNAL_CB_FUNCTION(on_analog_signal)
 {
        switch (sigmsg->channel->type) {
        case ZAP_CHAN_TYPE_FXO:
@@ -1027,7 +1093,7 @@ static switch_status_t load_config(void)
                                continue;
                        }
 
-                       if (zap_analog_configure_span(span, tonegroup, to, max, on_zap_signal) != ZAP_SUCCESS) {
+                       if (zap_analog_configure_span(span, tonegroup, to, max, on_analog_signal) != ZAP_SUCCESS) {
                                zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %d\n", span_id);
                                continue;
                        }
@@ -1041,6 +1107,65 @@ static switch_status_t load_config(void)
                }
        }
 
+       if ((spans = switch_xml_child(cfg, "pri_spans"))) {
+               for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
+                       char *id = (char *) switch_xml_attr_soft(myspan, "id");
+                       char *context = "default";
+                       char *dialplan = "XML";
+                       Q921NetUser_t mode = Q931_TE;
+                       Q931Dialect_t dialect = Q931_Dialect_National;
+                       uint32_t span_id = 0;
+                       zap_span_t *span = NULL;
+                       char *tonegroup = NULL;
+
+                       for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
+                               char *var = (char *) switch_xml_attr_soft(param, "name");
+                               char *val = (char *) switch_xml_attr_soft(param, "value");
+
+                               if (!strcasecmp(var, "tonegroup")) {
+                                       tonegroup = val;
+                               } else if (!strcasecmp(var, "mode")) {
+                                       mode = strcasecmp(val, "net") ? Q931_TE : Q931_NT;
+                               } else if (!strcasecmp(var, "dialect")) {
+                                       dialect = q931_str2Q931Diaelct_type(val);
+                                       if (dialect == Q931_Dialect_Count) {
+                                               dialect = Q931_Dialect_National;
+                                       }
+                               } else if (!strcasecmp(var, "context")) {
+                                       context = val;
+                               } else if (!strcasecmp(var, "dialplan")) {
+                                       dialplan = val;
+                               } 
+                       }
+                               
+                       if (!id) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
+                       }
+
+                       span_id = atoi(id);
+                       
+                       if (!tonegroup) {
+                               tonegroup = "us";
+                       }
+                       
+                       if (zap_span_find(span_id, &span) != ZAP_SUCCESS) {
+                               zap_log(ZAP_LOG_ERROR, "Error finding OpenZAP span %d\n", span_id);
+                               continue;
+                       }
+
+                       if (zap_isdn_configure_span(span, mode, dialect, on_isdn_signal) != ZAP_SUCCESS) {
+                               zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %d mode: %d dialect: %d error: %s\n", span_id, mode, dialect, span->last_error);
+                               continue;
+                       }
+
+                       SPAN_CONFIG[span->span_id].span = span;
+                       switch_copy_string(SPAN_CONFIG[span->span_id].context, context, sizeof(SPAN_CONFIG[span->span_id].context));
+                       switch_copy_string(SPAN_CONFIG[span->span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span->span_id].dialplan));
+
+                       zap_isdn_start(span);
+               }
+       }
+
 
        switch_xml_free(xml);
 
index 774f3bcd4f3f4883619ceda566cfe5ff3c532cce..a13ae8081461e57dcd006c8cf51e6ab40013aba6 100644 (file)
@@ -296,6 +296,9 @@ struct zap_caller_data {
        char aniII[25];
        char dnis[25];
        char rdnis[25];
+       int CRV;
+       uint8_t raw_data[1024];
+       uint32_t raw_data_len;
 };
 
 struct zap_channel {
index 9126a186afa384d443b20cdbc976c96a13391cea..57c29146c239a1bb2d23da90f4b5542fa090076b 100644 (file)
@@ -88,7 +88,7 @@ static void launch_channel(struct sangoma_pri *spri, int channo)
        memset(inframe, 0, MAX_BYTES);
        memset(outframe, 0, MAX_BYTES);
                
-       if (zap_channel_open("wanpipe", spri->span, channo, &chan) != ZAP_SUCCESS) {
+       if (zap_channel_open(spri->span, channo, &chan) != ZAP_SUCCESS) {
                printf("DEBUG cant open fd!\n");
        }
        
@@ -103,7 +103,7 @@ static void launch_channel(struct sangoma_pri *spri, int channo)
 #endif
        
 #if 1
-       if (zap_channel_command(chan, ZAP_COMMAND_ENABLE_TONE_DETECT, &tt) != ZAP_SUCCESS) {
+       if (zap_channel_command(chan, ZAP_COMMAND_ENABLE_DTMF_DETECT, &tt) != ZAP_SUCCESS) {
                printf("Critical Error: Failed to set dtmf detect!\n");
                zap_channel_close(&chan);
                exit(-1);
@@ -167,7 +167,7 @@ static void launch_channel(struct sangoma_pri *spri, int channo)
                        if (lead) {
                                continue;
                        } 
-                       zap_channel_write(chan, outframe, &len);
+                       zap_channel_write(chan, outframe, sizeof(outframe), &len);
                } else {
                        printf("BREAK");
                        break;
@@ -289,7 +289,8 @@ int main(int argc, char *argv[])
     printf("OpenZAP loaded\n");
 
 
-       
+       debug = PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE;
+
        if (sangoma_init_pri(&spri,
                                                 1,  // span
                                                 24, // dchan
index 865fe4f4767800432d78e07a18ba31c9909461f4..bf213699b689d616edcdea36a40017a767c3b9d1 100644 (file)
@@ -105,8 +105,8 @@ static int __pri_sangoma_read(struct pri *pri, void *buf, int buflen)
        memset(&((unsigned char*)buf)[res],0,2);
        res+=2;
 
-       print_bits(buf, res-2, bb, sizeof(bb), 1);
-       zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", res-2, LINE, bb);
+       //print_bits(buf, res-2, bb, sizeof(bb), 1, 0);
+       //zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", res-2, LINE, bb);
 
        return res;
 }
@@ -118,13 +118,13 @@ static int __pri_sangoma_write(struct pri *pri, void *buf, int buflen)
        zap_size_t len = buflen -2;
        char bb[4096] = "";
 
-       if (zap_channel_write(spri->zdchan, buf, &len) != ZAP_SUCCESS) {
+       if (zap_channel_write(spri->zdchan, buf, buflen, &len) != ZAP_SUCCESS) {
                printf("D-WRITE FAIL! [%s]\n", spri->zdchan->last_error);
         return 0;
        }
        
-       print_bits(buf, (int)buflen-2, bb, sizeof(bb), 1);
-       zap_log(ZAP_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)buflen-2, LINE, bb);
+       //print_bits(buf, (int)buflen-2, bb, sizeof(bb), 1, 0);
+       //zap_log(ZAP_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)buflen-2, LINE, bb);
 
        return (int) buflen;
 }
@@ -136,7 +136,7 @@ int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype,
 
        memset(spri, 0, sizeof(struct sangoma_pri));
 
-       if (zap_channel_open("wanpipe", span, dchan, &spri->zdchan) != ZAP_SUCCESS) {
+       if (zap_channel_open(span, dchan, &spri->zdchan) != ZAP_SUCCESS) {
                fprintf(stderr, "Unable to open DCHAN %d for span %d (%s)\n", dchan, span, strerror(errno));
        } else {
                if ((spri->pri = pri_new_cb(spri->zdchan->sockfd, node, swtype, __pri_sangoma_read, __pri_sangoma_write, spri))){
index 93af26f752697c4d7361e3cae0432579c94260cf..231215a4b18fccb20d693163411ce231da4df73e 100644 (file)
@@ -19,7 +19,7 @@ int main(int argc, char *argv[])
 
        printf("OpenZAP loaded\n");
 
-       if (zap_span_find("wanpipe", 1, &span) != ZAP_SUCCESS) {
+       if (zap_span_find(1, &span) != ZAP_SUCCESS) {
                fprintf(stderr, "Error finding OpenZAP span\n");
                goto done;
        }
index 009fafef40226f15a132dc5bc9a980b80a4d96b7..82d6706134968c29c09ce744f74720f90b88e5d0 100644 (file)
@@ -781,9 +781,12 @@ zap_status_t zap_channel_close(zap_channel_t **zchan)
 
        assert(zchan != NULL);
        check = *zchan;
-       assert(check != NULL);
        *zchan = NULL;
 
+       if (!check) {
+               return ZAP_FAIL;
+       }
+
        zap_mutex_lock(check->mutex);
        if (zap_test_flag(check, ZAP_CHANNEL_OPEN)) {
                status = check->zio->close(check);
@@ -1966,7 +1969,7 @@ void print_bits(uint8_t *b, int bl, char *buf, int blen, zap_endian_t e, uint8_t
        if (blen < (bl * 10) + 2) {
         return;
     }
-       
+
        zap_bitstream_init(&bs, b, bl, e, ss);
        last = bs.byte_index;   
        while((bit = zap_bitstream_get_bit(&bs)) > -1) {
index f9577e4798ef245e02bce633030187005ba9988b..36628a63095cf611c8c3a5d4b35a9bc1c598e58c 100644 (file)
@@ -71,6 +71,55 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
        assert(data != NULL);
 
        zap_log(ZAP_LOG_DEBUG, "Yay I got an event! Type:[%d] Size:[%d]\n", gen->MesType, gen->Size);
+       switch(gen->MesType) {
+       case Q931mes_SETUP:
+               {
+                       Q931ie_ChanID *chanid = Q931GetIEPtr(gen->ChanID, gen->buf);
+                       Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf);
+                       Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
+                       int chan_id = chanid->ChanSlot;
+                       zap_channel_t *zchan;
+                       zap_status_t status;
+                       zap_sigmsg_t sig;
+                       zap_isdn_data_t *data;
+                       int fail = 1;
+                       uint32_t cplen = mlen;
+
+                       if ((status = zap_channel_open(span->span_id, chan_id, &zchan) == ZAP_SUCCESS)) {
+                               zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING);
+                               sig.chan_id = zchan->chan_id;
+                               sig.span_id = zchan->span_id;
+                               sig.channel = zchan;
+                               sig.event_id = ZAP_SIGEVENT_START;
+                               data = zchan->span->isdn_data;
+                               
+                               memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
+
+                               zap_copy_string(zchan->caller_data.cid_num, callingnum->Digit, callingnum->Size - 3);
+                               zap_copy_string(zchan->caller_data.cid_name, callingnum->Digit, callingnum->Size - 3);
+                               zap_copy_string(zchan->caller_data.ani, callingnum->Digit, callingnum->Size - 3);
+                               zap_copy_string(zchan->caller_data.dnis, callednum->Digit, callednum->Size - 3);
+
+                               zchan->caller_data.CRV = gen->CRV;
+                               if (cplen > sizeof(zchan->caller_data.raw_data)) {
+                                       cplen = sizeof(zchan->caller_data.raw_data);
+                               }
+                               memcpy(zchan->caller_data.raw_data, msg, cplen);
+                               zchan->caller_data.raw_data_len = cplen;
+                               if ((status = data->sig_cb(&sig) == ZAP_SUCCESS)) {
+                                       fail = 0;
+                               }
+                       } 
+
+                       if (fail) {
+                               // add me 
+                       }
+                       
+               }
+               break;
+       default:
+               break;
+       }
 
        return 0;
 }
@@ -89,7 +138,7 @@ static int zap_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen)
        zap_size_t len = (zap_size_t) mlen;
 #ifdef IODEBUG
        char bb[4096] = "";
-       print_bits(msg, (int)len, bb, sizeof(bb), 1, 0);
+       print_bits(msg, (int)len, bb, sizeof(bb), ZAP_ENDIAN_LITTLE, 0);
        zap_log(ZAP_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)len, LINE, bb);
 
 #endif
@@ -98,12 +147,49 @@ static int zap_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen)
        return zap_channel_write(span->isdn_data->dchan, msg, len, &len) == ZAP_SUCCESS ? 0 : -1;
 }
 
+static void state_advance(zap_channel_t *zchan)
+{
+       Q931mes_Generic *gen = (Q931mes_Generic *) zchan->caller_data.raw_data;
+       zap_isdn_data_t *data = zchan->span->isdn_data;
+
+       zap_log(ZAP_LOG_ERROR, "%d:%d STATE [%s]\n", 
+                       zchan->span_id, zchan->chan_id, zap_channel_state2str(zchan->state));
+
+
+       switch (zchan->state) {
+       case ZAP_CHANNEL_STATE_UP:
+               {
+                       printf("XXXXXXXXXXXXXXXX answer %d\n", zchan->caller_data.raw_data_len);
+                       gen->MesType = Q931mes_CONNECT;
+                       gen->BearerCap = 0;
+                       gen->CRVFlag = 1;//!(gen->CRVFlag);
+                       Q931Rx43(&data->q931, (void *)gen, zchan->caller_data.raw_data_len);
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+static void check_state(zap_span_t *span)
+{
+       uint32_t j;
+       
+       for(j = 1; j <= span->chan_count; j++) {
+               if (zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) {
+                       state_advance(&span->channels[j]);
+                       zap_clear_flag_locked((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE);
+               }
+       }
+}
+
 static void *zap_isdn_run(zap_thread_t *me, void *obj)
 {
        zap_span_t *span = (zap_span_t *) obj;
        zap_isdn_data_t *data = span->isdn_data;
        unsigned char buf[1024];
        zap_size_t len = sizeof(buf);
+       int errs = 0;
 
 #ifdef WIN32
     timeBeginPeriod(1);
@@ -118,29 +204,34 @@ static void *zap_isdn_run(zap_thread_t *me, void *obj)
                zap_status_t status = zap_channel_wait(data->dchan, &flags, 100);
 
                Q921TimerTick(&data->q921);
-
+               check_state(span);
+               
                switch(status) {
                case ZAP_FAIL:
                        {
                                zap_log(ZAP_LOG_ERROR, "D-Chan Read Error!\n");
                                snprintf(span->last_error, sizeof(span->last_error), "D-Chan Read Error!");
-                               goto done;
+                               if (++errs == 10) {
+                                       goto done;
+                               }
                        }
                        break;
                case ZAP_TIMEOUT:
                        {
                                /*zap_log(ZAP_LOG_DEBUG, "Timeout!\n");*/
                                /*Q931TimeTick(data->q931, L3ULONG ms);*/
+                               errs = 0;
                        }
                        break;
                default:
                        {
+                               errs = 0;
                                if (flags & ZAP_READ) {
                                        len = sizeof(buf);
                                        if (zap_channel_read(data->dchan, buf, &len) == ZAP_SUCCESS) {
 #ifdef IODEBUG
                                                char bb[4096] = "";
-                                               print_bits(buf, (int)len, bb, sizeof(bb), 1, 0);
+                                               print_bits(buf, (int)len, bb, sizeof(bb), ZAP_ENDIAN_LITTLE, 0);
                                                zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)len, LINE, bb);
 #endif
 
@@ -191,7 +282,7 @@ zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931D
        zap_channel_t *dchans[2] = {0};
 
        if (span->signal_type) {
-               snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling.");
+               snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling [%d].", span->signal_type);
                return ZAP_FAIL;
        }
 
@@ -246,6 +337,7 @@ zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931D
 
        span->isdn_data->q931.autoRestartAck = 1;
 
+
        span->signal_type = ZAP_SIGTYPE_ISDN;
        
        return ZAP_SUCCESS;