]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
inbound calls milestone
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 14 Jun 2007 03:54:02 +0000 (03:54 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 14 Jun 2007 03:54:02 +0000 (03:54 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@255 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/freetdm/mod_openzap/mod_openzap.c
libs/freetdm/src/include/openzap.h
libs/freetdm/src/include/zap_types.h
libs/freetdm/src/isdn/Q931api.c
libs/freetdm/src/isdn/Q931ie.c
libs/freetdm/src/priserver.c
libs/freetdm/src/zap_analog.c
libs/freetdm/src/zap_io.c
libs/freetdm/src/zap_isdn.c

index e4793fe8071aa0d0409feef39e94f24029f4061d..639fc18f6f4c3df743c9a118e1abdc2135789885 100644 (file)
@@ -319,6 +319,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
        case ZAP_CHAN_TYPE_B:
                {
                        if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
+                               tech_pvt->zchan->caller_data.hangup_cause = switch_channel_get_cause(channel);
                                zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_HANGUP);
                        }
                }
@@ -638,7 +639,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
        }
 }
 
-static const switch_state_handler_table_t channel_event_handlers = {
+static switch_state_handler_table_t channel_event_handlers = {
        /*.on_init */ channel_on_init,
        /*.on_ring */ channel_on_ring,
        /*.on_execute */ channel_on_execute,
@@ -647,7 +648,7 @@ static const switch_state_handler_table_t channel_event_handlers = {
        /*.on_transmit */ channel_on_transmit
 };
 
-static const switch_io_routines_t channel_io_routines = {
+static switch_io_routines_t channel_io_routines = {
        /*.outgoing_channel */ channel_outgoing_channel,
        /*.read_frame */ channel_read_frame,
        /*.write_frame */ channel_write_frame,
@@ -658,7 +659,7 @@ static const switch_io_routines_t channel_io_routines = {
        /*.receive_message*/ channel_receive_message
 };
 
-static const switch_endpoint_interface_t channel_endpoint_interface = {
+static switch_endpoint_interface_t channel_endpoint_interface = {
        /*.interface_name */ "openzap",
        /*.io_routines */ &channel_io_routines,
        /*.event_handlers */ &channel_event_handlers,
@@ -666,7 +667,7 @@ static const switch_endpoint_interface_t channel_endpoint_interface = {
        /*.next */ NULL
 };
 
-static const switch_loadable_module_interface_t channel_module_interface = {
+static switch_loadable_module_interface_t channel_module_interface = {
        /*.module_name */ modname,
        /*.endpoint_interface */ &channel_endpoint_interface,
        /*.timer_interface */ NULL,
index a13ae8081461e57dcd006c8cf51e6ab40013aba6..316b4d3af403495f21459f1eff31af5e3a73ce31 100644 (file)
 
 #define zap_set_state_locked(obj, s) if ( obj->state == s ) {                  \
                zap_log(ZAP_LOG_WARNING, "Why bother changing state from %s to %s\n", zap_channel_state2str(obj->state), zap_channel_state2str(s)); \
-       } else {                                                                                                                        \
+       } else if (zap_test_flag(obj, ZAP_CHANNEL_READY)) {                                                                     \
                int st = obj->state;                                                                                    \
                zap_channel_set_state(obj, s);                                                                  \
                if (obj->state == s) zap_log(ZAP_LOG_DEBUG, "Changing state from %s to %s\n", zap_channel_state2str(st), zap_channel_state2str(s)); \
@@ -297,6 +297,7 @@ struct zap_caller_data {
        char dnis[25];
        char rdnis[25];
        int CRV;
+       int hangup_cause;       
        uint8_t raw_data[1024];
        uint32_t raw_data_len;
 };
index c6ae837986e41fdd47bf991cfdff81a1bdb57c0d..b81f5338c1c9cd4c43557b9687e550d120621dc7 100644 (file)
@@ -224,7 +224,8 @@ typedef enum {
 
 typedef enum {
        ZAP_SPAN_CONFIGURED = (1 << 0),
-       ZAP_SPAN_READY = (1 << 1)
+       ZAP_SPAN_READY = (1 << 1),
+       ZAP_SPAN_STATE_CHANGE = (1 << 2)
 } zap_span_flag_t;
 
 typedef enum {
@@ -258,10 +259,13 @@ typedef enum {
        ZAP_CHANNEL_STATE_DIALING,
        ZAP_CHANNEL_STATE_GET_CALLERID,
        ZAP_CHANNEL_STATE_CALLWAITING,
+       ZAP_CHANNEL_STATE_TERMINATING,
+       ZAP_CHANNEL_STATE_RESTART,
        ZAP_CHANNEL_STATE_INVALID
 } zap_channel_state_t;
 #define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", \
-               "RING", "BUSY", "ATTN", "IDLE", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", "INVALID"
+               "RING", "BUSY", "ATTN", "IDLE", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
+               "TERMINATING", "RESTART", "INVALID"
 ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t)
 
 typedef enum {
@@ -285,7 +289,6 @@ typedef enum {
        ZAP_CHANNEL_CALLERID_DETECT = (1 << 17)
 } zap_channel_flag_t;
 
-
 typedef struct zap_channel zap_channel_t;
 typedef struct zap_event zap_event_t;
 typedef struct zap_sigmsg zap_sigmsg_t;
index 1ac2a56b96dfed532796c9497571aecb6c40ee14..2e4e0063a6bd7880070c05a35a90d619348123eb 100644 (file)
@@ -518,8 +518,8 @@ L3INT Q931Disconnect(Q931_TrunkInfo_t *pTrunk, L3INT iTo, L3INT iCRV, L3INT iCau
 L3INT Q931ReleaseComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf)
 {
     Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace];
-       ptr->MesType = Q931mes_RESTART_ACKNOWLEDGE;
-
+       ptr->MesType = Q931mes_RELEASE_COMPLETE;
+       ptr->CRVFlag = !(ptr->CRVFlag);
        return Q931Tx32(pTrunk,buf,ptr->Size);
 }
 
@@ -528,7 +528,10 @@ L3INT Q931AckRestart(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf)
        L3INT RetCode;
 
     Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace];
-       ptr->MesType = Q931mes_RELEASE_COMPLETE;
+       ptr->MesType = Q931mes_RESTART_ACKNOWLEDGE;
+       if (ptr->CRV) {
+               ptr->CRVFlag = !(ptr->CRVFlag);
+       }
 
        RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4);
 
index 9e2f68720613243a91c4c37aa35ddf2ca1707316..0ea4251dbf630170152d18b411f8cafacfdce4f4 100644 (file)
@@ -715,19 +715,22 @@ L3INT Q931Uie_CalledNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR
     pie->TypNum = (IBuf[Octet+Off] >> 4) & 0x07;
     pie->NumPlanID = IBuf[Octet+Off] & 0x0f;
     Octet ++;
-    
+
     /* Octet 4*/
-    for (x = 0; x < IESize - 1; x++)
-    {
+    x=0;
+    do{
         pie->Digit[x] = IBuf[Octet+Off] & 0x7f;
         Off++;
-    }
+        x++;
+    } while((IBuf[Octet+Off]&0x80) == 0 && Q931MoreIE());
+
+       pie->Digit[x] = '\0';
 
     Q931SetIE(*pIE, *OOff);
 
        *IOff = (*IOff) + Octet + Off;
-    *OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x - 1;
-    pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x - 1);
+    *OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x;
+    pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x);
 
     return Q931E_NO_ERROR;
 }
@@ -824,15 +827,17 @@ L3INT Q931Uie_CallingNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHA
         pie->Digit[x] = IBuf[Octet+Off] & 0x7f;
         Off++;
         x++;
-    }while((IBuf[Octet+Off]&0x80) == 0 && Q931MoreIE());
+    } while((IBuf[Octet+Off]&0x80) == 0 && Q931MoreIE());
+
+       pie->Digit[x] = '\0';
 
     Q931IESizeTest(Q931E_CALLINGNUM);
 
     Q931SetIE(*pIE, *OOff);
 
     *IOff = (*IOff) + Octet + Off;
-    *OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x - 1;
-    pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x - 1);
+    *OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x;
+    pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x);
 
     return Q931E_NO_ERROR;
 }
index 57c29146c239a1bb2d23da90f4b5542fa090076b..6bb5e02965587a962d56bb08b52e08e6b0236ad2 100644 (file)
@@ -180,7 +180,7 @@ static void launch_channel(struct sangoma_pri *spri, int channo)
        close(file);
        //close(ifd);
 
-
+       pri_hangup(spri->pri, channo, 16);
        if (zap_channel_close(&chan) != ZAP_SUCCESS) {
                printf("Critical Error: Failed to close channel [%s]\n", chan->last_error);
        }
index 7bca77d10a475338c2d4788a735979e5ebd07a00..0ad28c92bda10f8bf584a4a442ea0d1fab75ee3e 100644 (file)
@@ -307,6 +307,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                                        if (done) {
                                                zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP);
                                                zap_clear_flag_locked(chan, ZAP_CHANNEL_STATE_CHANGE);
+                                               zap_clear_flag_locked(chan->span, ZAP_SPAN_STATE_CHANGE);
                                                chan->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK] = 0;
                                        }
                                }
@@ -328,6 +329,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                        }
                } else {
                        zap_clear_flag_locked(chan, ZAP_CHANNEL_STATE_CHANGE);
+                       zap_clear_flag_locked(chan->span, ZAP_SPAN_STATE_CHANGE);
                        indicate = 0;
                        state_counter = 0;
                        zap_log(ZAP_LOG_DEBUG, "Executing state handler for %s\n", zap_channel_state2str(chan->state));
@@ -631,6 +633,7 @@ static zap_status_t process_event(zap_span_t *span, zap_event_t *event)
                        if (event->channel->state == ZAP_CHANNEL_STATE_CALLWAITING) {
                                zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_UP);
                                zap_clear_flag_locked(event->channel, ZAP_CHANNEL_STATE_CHANGE);
+                               zap_clear_flag_locked(event->channel->span, ZAP_SPAN_STATE_CHANGE);
                                event->channel->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK] = 0;
                        } 
 
index 82d6706134968c29c09ce744f74720f90b88e5d0..8f5e0d08f6c39112deb86df74b12aa2ec7ac25f5 100644 (file)
@@ -511,26 +511,35 @@ zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t sta
        
        zap_mutex_lock(zchan->mutex);
 
-       if (zchan->state == ZAP_CHANNEL_STATE_DOWN) {
-
-               switch(state) {
-               case ZAP_CHANNEL_STATE_BUSY:
-                       ok = 0;
-                       break;
-               default:
-                       break;
-               }
+       if (!zap_test_flag(zchan, ZAP_CHANNEL_READY)) {
+               return ZAP_FAIL;
        }
 
-       if (zchan->state == ZAP_CHANNEL_STATE_BUSY) {
-
-               switch(state) {
-               case ZAP_CHANNEL_STATE_UP:
-                       ok = 0;
-                       break;
-               default:
-                       break;
+       switch(zchan->state) {
+       case ZAP_CHANNEL_STATE_DOWN:
+               {
+                       switch(state) {
+                       case ZAP_CHANNEL_STATE_BUSY:
+                       case ZAP_CHANNEL_STATE_HANGUP:
+                       case ZAP_CHANNEL_STATE_TERMINATING:
+                               ok = 0;
+                               break;
+                       default:
+                               break;
+                       }
                }
+       case ZAP_CHANNEL_STATE_BUSY:
+               {
+                       switch(state) {
+                       case ZAP_CHANNEL_STATE_UP:
+                               ok = 0;
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       default:
+               break;
        }
 
        if (state == zchan->state) {
@@ -539,6 +548,7 @@ zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t sta
 
        if (ok) {
                zap_set_flag(zchan, ZAP_CHANNEL_STATE_CHANGE);  
+               zap_set_flag(zchan->span, ZAP_SPAN_STATE_CHANGE);
                zchan->last_state = zchan->state; 
                zchan->state = state;
        }
index 35b828c38704407b54822a59a9795a94c42ae23d..d114be55d0d722a4c4df0b1c77b3f0938d5052e2 100644 (file)
@@ -66,52 +66,74 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
        zap_span_t *span = (zap_span_t *) pvt;
        zap_isdn_data_t *data = span->isdn_data;
        Q931mes_Generic *gen = (Q931mes_Generic *) msg;
-
+       Q931ie_ChanID *chanid = Q931GetIEPtr(gen->ChanID, gen->buf);
+       int chan_id = chanid->ChanSlot;
+       zap_channel_t *zchan = NULL;
+       
        assert(span != NULL);
        assert(data != NULL);
+       
+       if (chan_id) {
+               zchan = &span->channels[chan_id];
+       }
 
-       zap_log(ZAP_LOG_DEBUG, "Yay I got an event! Type:[%d] Size:[%d]\n", gen->MesType, gen->Size);
+       zap_log(ZAP_LOG_DEBUG, "Yay I got an event! Type:[%02x] Size:[%d]\n", gen->MesType, gen->Size);
        switch(gen->MesType) {
+       case Q931mes_RESTART:
+               {
+                       if (zchan) {
+                               zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART);
+                       } else {
+                               uint32_t i;
+                               for (i = 0; i < span->chan_count; i++) {
+                                       zap_set_state_locked((&span->channels[i]), ZAP_CHANNEL_STATE_RESTART);
+                               }
+                       }
+               }
+               break;
+       case Q931mes_RELEASE_COMPLETE:
+               {
+                       zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
+               }
+               break;
+       case Q931mes_DISCONNECT:
+               {
+                       zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_TERMINATING);
+               }
+               break;
        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, (char *)callingnum->Digit, callingnum->Size - 3);
-                               zap_copy_string(zchan->caller_data.cid_name, (char *)callingnum->Digit, callingnum->Size - 3);
-                               zap_copy_string(zchan->caller_data.ani, (char *)callingnum->Digit, callingnum->Size - 3);
-                               zap_copy_string(zchan->caller_data.dnis, (char *)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)) {
+                               if (zchan->state == ZAP_CHANNEL_STATE_DOWN) {
+                                       memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
+
+                                       zap_set_string(zchan->caller_data.cid_num, callingnum->Digit);
+                                       zap_set_string(zchan->caller_data.cid_name, callingnum->Digit);
+                                       zap_set_string(zchan->caller_data.ani, callingnum->Digit);
+                                       zap_set_string(zchan->caller_data.dnis, callednum->Digit);
+
+                                       zchan->caller_data.CRV = gen->CRV;
+                                       if (cplen > sizeof(zchan->caller_data.raw_data)) {
+                                               cplen = sizeof(zchan->caller_data.raw_data);
+                                       }
+                                       gen->CRVFlag = !(gen->CRVFlag);
+                                       memcpy(zchan->caller_data.raw_data, msg, cplen);
+                                       zchan->caller_data.raw_data_len = cplen;
+                                       zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING);
                                        fail = 0;
-                               }
+                               } 
                        } 
 
                        if (fail) {
+                               zap_log(ZAP_LOG_CRIT, "FIX ME!\n");
                                // add me 
                        }
                        
@@ -147,39 +169,80 @@ 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)
+static __inline__ 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_sigmsg_t sig;
+       zap_status_t status;
 
        zap_log(ZAP_LOG_ERROR, "%d:%d STATE [%s]\n", 
                        zchan->span_id, zchan->chan_id, zap_channel_state2str(zchan->state));
 
+       memset(&sig, 0, sizeof(sig));
+       sig.chan_id = zchan->chan_id;
+       sig.span_id = zchan->span_id;
+       sig.channel = zchan;
 
        switch (zchan->state) {
+       case ZAP_CHANNEL_STATE_RING:
+               {
+                       sig.event_id = ZAP_SIGEVENT_START;
+                       if ((status = data->sig_cb(&sig) != ZAP_SUCCESS)) {
+                               zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP);
+                       }
+
+               }
+               break;
+       case ZAP_CHANNEL_STATE_RESTART:
+               {
+                       zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
+                       zap_channel_close(&zchan);
+               }
+               break;
        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;
+       case ZAP_CHANNEL_STATE_HANGUP:
+               {
+                       Q931ie_Cause cause;
+                       gen->MesType = Q931mes_DISCONNECT;
+                       cause.IEId = Q931ie_CAUSE;
+                       cause.Size = sizeof(Q931ie_Cause);
+                       cause.CodStand  = 0;
+                       cause.Location = 1;
+                       cause.Recom = 1;
+                       cause.Value = zchan->caller_data.hangup_cause;
+                       *cause.Diag = '\0';
+                       gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
+                       Q931Rx43(&data->q931, (L3UCHAR *) gen, gen->Size);
+               }
+               break;
+       case ZAP_CHANNEL_STATE_TERMINATING:
+               {
+                       gen->MesType = Q931mes_RELEASE;
+                       Q931Rx43(&data->q931, (void *)gen, gen->Size);
+               }
        default:
                break;
        }
 }
 
-static void check_state(zap_span_t *span)
+static __inline__ 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);
+       if (zap_test_flag(span, ZAP_SPAN_STATE_CHANGE)) {
+               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);
+                       }
                }
+               zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE);
        }
 }