diff --git a/mod_openzap/mod_openzap.c b/mod_openzap/mod_openzap.c
index b93a5ab..0cbd404 100644
--- a/mod_openzap/mod_openzap.c
+++ b/mod_openzap/mod_openzap.c
@@ -698,6 +698,9 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
 				zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
 				zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
 			} else {
+				if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS) {
+					zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
+				}
 				zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA);
 			}
 		}
@@ -707,6 +710,12 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
 			if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
 				zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
 			} else {
+				if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS) {
+					zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
+				}
+				if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS_MEDIA) {
+					zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA);
+				}
 				zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP);
 			}
 		}
diff --git a/src/isdn/Q921.c b/src/isdn/Q921.c
index a682c23..d6beb39 100644
--- a/src/isdn/Q921.c
+++ b/src/isdn/Q921.c
@@ -576,6 +576,7 @@ static int Q921LogMesg(L2TRUNK trunk, Q921LogLevel_t level, L2UCHAR received, L2
 	if(!mes)
 		return 0;
 
+	memset(buf, 0, sizeof(buf));
 
 	left = sizeof(buf) - 1;
 
@@ -598,6 +599,8 @@ static int Q921LogMesg(L2TRUNK trunk, Q921LogLevel_t level, L2UCHAR received, L2
 		L2UCHAR *pmes = mes + trunk->Q921HeaderSpace;
 		struct Q921_Link *link;
 
+		memset(pbuf, 0, sizeof(pbuf));
+
 		pleft   = sizeof(pbuf);
 		poffset = 0;
 
@@ -1698,6 +1701,26 @@ static int Q921SendSABME(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf)
 	return Q921SendU(trunk, Sapi, cr, Tei, pf, 0x0f, mes, trunk->Q921HeaderSpace+3);
 }
 
+/**
+ * Q921SendFRMR
+ * \brief	Reject last frame
+ *
+ */
+#ifdef _UNUSED_
+static int Q921SendFRMR(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf)
+{
+	struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei);
+	L2UCHAR mes[25];
+
+	mes[4] = 0;
+	mes[5] = 0;
+	mes[6] = link->vs;
+	mes[7] = link->vr;
+	mes[8] = 0x07;	/* = frame exceeded N201 length, control field invalid and undefined */
+
+	return Q921SendU(trunk, Sapi, cr, Tei, pf, 0x11, mes, trunk->Q921HeaderSpace+3);
+}
+#endif
 
 /**
  * Q921Start
@@ -2916,6 +2939,11 @@ int Q921Rx12(L2TRUNK trunk)
 		rs  = size - trunk->Q921HeaderSpace;
 		mes = &smes[trunk->Q921HeaderSpace];
 
+		if(rs > trunk->N201Limit) {
+			Q921Log(trunk, Q921_LOG_ERROR, "Message too large: %d bytes (max. %d bytes), discarding!", rs, trunk->N201Limit);
+			return 0;
+		}
+
 		Q921LogMesg(trunk, Q921_LOG_DEBUG, 1, mes, rs, "New packet received (%d bytes)", rs);
 
 		/* common fields: get sapi, tei and cr */
diff --git a/src/isdn/Q931.c b/src/isdn/Q931.c
index 6591613..90ab46e 100644
--- a/src/isdn/Q931.c
+++ b/src/isdn/Q931.c
@@ -378,6 +378,10 @@ L3INT Q931Rx23(Q931_TrunkInfo_t *pTrunk, L3INT ind, L3UCHAR tei, L3UCHAR * buf,
 		/* Message Type */
 		m->MesType = Mes[IOff++];
 
+		/* Store tei */
+		m->Tei = tei;
+
+#if 0
 		/* d'oh a little ugly but this saves us from:
 		 *	a) doing Q.921 work in the lower levels (extracting the TEI ourselves)
 		 *	b) adding a tei parameter to _all_ Proc functions
@@ -391,8 +395,9 @@ L3INT Q931Rx23(Q931_TrunkInfo_t *pTrunk, L3INT ind, L3UCHAR tei, L3UCHAR * buf,
 				pTrunk->call[callIndex].Tei = tei;
 			}
 		}
+#endif
 
-		Q931Log(pTrunk, Q931_LOG_DEBUG, "Received message from Q.921 (ind %d, tei %d, size %d)\nMesType: %d, CRVFlag %d (%s), CRV %d (Dialect: %d)\n", ind, tei, Size,
+		Q931Log(pTrunk, Q931_LOG_DEBUG, "Received message from Q.921 (ind %d, tei %d, size %d)\nMesType: %d, CRVFlag %d (%s), CRV %d (Dialect: %d)\n", ind, m->Tei, Size,
 						 m->MesType, m->CRVFlag, m->CRVFlag ? "Terminator" : "Originator", m->CRV, pTrunk->Dialect);
 
 		RetCode = Q931Umes[pTrunk->Dialect][m->MesType](pTrunk, Mes, (Q931mes_Generic *)pTrunk->L3Buf, IOff, Size - L2HSize);
diff --git a/src/isdn/Q931StateNT.c b/src/isdn/Q931StateNT.c
index af74ef0..d1eff42 100644
--- a/src/isdn/Q931StateNT.c
+++ b/src/isdn/Q931StateNT.c
@@ -361,6 +361,9 @@ L3INT Q931ProcSetupNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom)
             return ret;
         }
 
+	/* store TEI in call */
+	pTrunk->call[callIndex].Tei = pMes->Tei;
+
         /* Send setup indication to user */
         ret = Q931Tx34(pTrunk,(L3UCHAR*)pMes,pMes->Size);
         if(ret != Q931E_NO_ERROR)
diff --git a/src/isdn/include/Q931.h b/src/isdn/include/Q931.h
index 2687930..c9311fa 100644
--- a/src/isdn/include/Q931.h
+++ b/src/isdn/include/Q931.h
@@ -563,9 +563,10 @@ typedef struct
 *****************************************************************************/
 typedef struct
 {
-    L3UINT			Size;           /* Size of message in bytes             */
+    L3UINT          Size;           /* Size of message in bytes             */
     L3UCHAR         ProtDisc;       /* Protocol Discriminator               */
     L3UCHAR         MesType;        /* Message type                         */
+    L3UCHAR         Tei;            /* TEI                                  */
     L3UCHAR         CRVFlag;        /* Call reference value flag            */
     L3INT           CRV;            /* Call reference value                 */
 
diff --git a/src/ozmod/ozmod_isdn/ozmod_isdn.c b/src/ozmod/ozmod_isdn/ozmod_isdn.c
index 78792ba..b3b450a 100644
--- a/src/ozmod/ozmod_isdn/ozmod_isdn.c
+++ b/src/ozmod/ozmod_isdn/ozmod_isdn.c
@@ -72,7 +72,6 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
 	Q931ie_CalledNum *ptrCalledNum;
 	Q931ie_Display Display, *ptrDisplay;
 	Q931ie_HLComp HLComp;			/* High-Layer Compatibility IE */
-	Q931ie_SendComplete SComplete;		/* Sending Complete IE */
 	Q931ie_ProgInd Progress;		/* Progress Indicator IE */
 	zap_status_t status = ZAP_FAIL;
 	zap_isdn_data_t *isdn_data = span->signal_data;
@@ -177,12 +176,6 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
 	HLComp.HLCharID  = 1;	/* Telephony = 1, Fax G2+3 = 4, Fax G4 = 65 (Class I)/ 68 (Class II or III) */
 	gen->HLComp = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &HLComp);
 
-	/*
-	 * Sending complete IE (or some NT stuff waits forever in Q.931 overlap dial state...)
-	 */
-	SComplete.IEId = Q931ie_SENDING_COMPLETE;
-//	gen->SendComplete = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &SComplete);
-
 	caller_data->call_state = ZAP_CALLER_STATE_DIALING;
 	Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
 	
@@ -299,6 +292,7 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 	zap_isdn_data_t *isdn_data = span->signal_data;
 	Q931mes_Generic *gen = (Q931mes_Generic *) msg;
 	int chan_id = 0;
+	int chan_hunt = 0;
 	zap_channel_t *zchan = NULL;
 	zap_caller_data_t *caller_data = NULL;
 
@@ -309,6 +303,14 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 			chan_id = chanid->ChanSlot;
 		else
 			chan_id = chanid->InfoChanSel;
+
+		/* "any" channel specified */
+		if(chanid->InfoChanSel == 3) {
+			chan_hunt++;
+		}
+	} else if (ZAP_SPAN_IS_NT(span)) {
+		/* no channel ie */
+		chan_hunt++;
 	}
 
 	assert(span != NULL);
@@ -346,7 +348,7 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 		zchan = isdn_data->channels_remote_crv[gen->CRV];
 	}
 
-	zap_log(ZAP_LOG_DEBUG, "zchan %x source isdn_data->channels_%s_crv[%#hx]\n", zchan, gen->CRVFlag ? "local" : "remote", gen->CRV);
+	zap_log(ZAP_LOG_DEBUG, "zchan %x (%d:%d) source isdn_data->channels_%s_crv[%#hx]\n", zchan, zchan ? zchan->span_id : -1, zchan ? zchan->chan_id : -1, gen->CRVFlag ? "local" : "remote", gen->CRV);
 
 
 	if (gen->ProtDisc == 3) {
@@ -491,6 +493,8 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 				Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf);
 				Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
 				int fail = 1;
+				int fail_cause = 0;
+				int overlap_dial = 0;
 				uint32_t cplen = mlen;
 
 				if(zchan && zchan == isdn_data->channels_remote_crv[gen->CRV]) {
@@ -504,8 +508,60 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 				}
 				
 				zchan = NULL;
-				if (chan_id < ZAP_MAX_CHANNELS_SPAN && chan_id <= span->chan_count) {
-					zchan = &span->channels[chan_id];
+				/*
+				 * Channel selection for incoming calls:
+				 */
+				if (ZAP_SPAN_IS_NT(span) && chan_hunt) {
+					int x;
+
+					/*
+					 * In NT-mode with channel selection "any",
+					 * try to find a free channel
+					 */
+					for (x = 1; x <= span->chan_count; x++) {
+						zap_channel_t *zc = &span->channels[x];
+
+						if (!zap_test_flag(zc, ZAP_CHANNEL_INUSE) && zc->state == ZAP_CHANNEL_STATE_DOWN) {
+							zchan = zc;
+							break;
+						}
+					}
+				}
+				else if (!ZAP_SPAN_IS_NT(span) && chan_hunt) {
+					/*
+					 * In TE-mode this ("any") is invalid
+					 */
+					fail_cause = ZAP_CAUSE_CHANNEL_UNACCEPTABLE;
+
+					zap_log(ZAP_LOG_ERROR, "Invalid channel selection in incoming call (network side didn't specify a channel)\n");
+				}
+				else {
+					/*
+					 * Otherwise simply try to select the channel we've been told
+					 *
+					 * TODO: NT mode is abled to select a different channel if the one chosen
+					 *       by the TE side is already in use
+					 */
+					if (chan_id > 0 && chan_id < ZAP_MAX_CHANNELS_SPAN && chan_id <= span->chan_count) {
+						zchan = &span->channels[chan_id];
+					}
+					else {
+						/* invalid channel id */
+						fail_cause = ZAP_CAUSE_CHANNEL_UNACCEPTABLE;
+
+						zap_log(ZAP_LOG_ERROR, "Invalid channel selection in incoming call (none selected or out of bounds)\n");
+					}
+				}
+
+				if (!callednum || !strlen(callednum->Digit)) {
+					if (ZAP_SPAN_IS_NT(span)) {
+						zap_log(ZAP_LOG_NOTICE, "No destination number found, assuming overlap dial\n");
+						overlap_dial++;
+					}
+					else {
+						zap_log(ZAP_LOG_ERROR, "No destination number found\n");
+						zchan = NULL;
+					}
 				}
 
 				if (zchan) {
@@ -552,7 +608,6 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 						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;
 					} 
 				} 
@@ -567,7 +622,7 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 					cause.Location = 1;
 					cause.Recom = 1;
 					//should we be casting here.. or do we need to translate value?
-					cause.Value = (unsigned char) ZAP_CAUSE_WRONG_CALL_STATE;
+					cause.Value = (unsigned char)((fail_cause) ? fail_cause : ZAP_CAUSE_WRONG_CALL_STATE);
 					*cause.Diag = '\0';
 					gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
 					Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
@@ -584,6 +639,7 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 					
 				} else {
 					Q931ie_ProgInd progress;
+					Q931ie_ChanID ChanID;
 
 					/*
 					 * Setup Progress indicator
@@ -594,6 +650,37 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 					progress.Location = 1;	/* private network serving the local user */
 					progress.ProgDesc = 1;	/* call is not end-to-end isdn = 1, in-band information available = 8 */
 					gen->ProgInd = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &progress);
+
+					/*
+					 * Update Channel ID IE
+					 */
+					Q931InitIEChanID(&ChanID);
+					ChanID.IntType = ZAP_SPAN_IS_BRI(zchan->span) ? 0 : 1;	/* PRI = 1, BRI = 0 */
+					ChanID.PrefExcl = ZAP_SPAN_IS_NT(zchan->span) ? 1 : 0;  /* Exclusive in NT-mode = 1, Preferred otherwise = 0 */
+					if(ChanID.IntType) {
+						ChanID.InfoChanSel = 1;		/* None = 0, See Slot = 1, Any = 3 */
+						ChanID.ChanMapType = 3;		/* B-Chan */
+						ChanID.ChanSlot = (unsigned char)zchan->chan_id;
+					} else {
+						ChanID.InfoChanSel = (unsigned char)zchan->chan_id & 0x03;	/* None = 0, B1 = 1, B2 = 2, Any = 3 */
+					}
+					gen->ChanID = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &ChanID);
+
+					if (overlap_dial) {
+						/*
+						 * Send SETUP ACK
+						 */
+						gen->MesType = Q931mes_SETUP_ACKNOWLEDGE;
+						gen->CRVFlag = 1;	/* inbound call */
+						Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
+
+						zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DIALTONE);
+					} else {
+						/*
+						 * Advance to RING state
+						 */
+						zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING);
+					}
 				}
 			}
 			break;
@@ -609,6 +696,48 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 			}
 			break;
 
+		case Q931mes_INFORMATION:
+			{
+				if (zchan) {
+					zap_log(ZAP_LOG_CRIT, "Received INFORMATION message for channel %d\n", zchan->chan_id);
+
+					if (zchan->state == ZAP_CHANNEL_STATE_DIALTONE) {
+						char digit = '\0';
+
+						/*
+						 * overlap dial digit indication
+						 */
+						if (Q931IsIEPresent(gen->CalledNum)) {
+							Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
+							int pos;
+
+							digit = callednum->Digit[strlen(callednum->Digit) - 1];
+							if (digit == '#') {
+								callednum->Digit[strlen(callednum->Digit) - 1] = '\0';
+							}
+
+							/* TODO: make this more safe with strncat() */
+							pos = strlen(zchan->caller_data.cid_num.digits);
+							strcat(&zchan->caller_data.cid_num.digits[pos], callednum->Digit);
+							strcat(&zchan->caller_data.cid_name[pos],       callednum->Digit);
+							strcat(&zchan->caller_data.ani.digits[pos],     callednum->Digit);
+							strcat(&zchan->caller_data.dnis.digits[pos],    callednum->Digit);
+
+							zap_log(ZAP_LOG_DEBUG, "Received new overlap digit (%s), destination number: %s\n", callednum->Digit, zchan->caller_data.cid_num.digits);
+						}
+
+						if (Q931IsIEPresent(gen->SendComplete) || digit == '#') {
+							zap_log(ZAP_LOG_DEBUG, "Leaving overlap dial mode\n");
+
+							zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING);
+						}
+					}
+				} else {
+					zap_log(ZAP_LOG_CRIT, "Received INFORMATION message with no matching channel\n");
+				}
+			}
+			break;
+
 		default:
 			zap_log(ZAP_LOG_CRIT, "Received unhandled message %d (%#x)\n", (int)gen->MesType, (int)gen->MesType);
 			break;
@@ -696,10 +825,42 @@ static __inline__ void state_advance(zap_channel_t *zchan)
 				gen->MesType = Q931mes_CALL_PROCEEDING;
 				gen->CRVFlag = 1;	/* inbound */
 
+				if (ZAP_SPAN_IS_NT(zchan->span)) {
+					Q931ie_ChanID ChanID;
+
+					/*
+					 * Set new Channel ID
+					 */
+					Q931InitIEChanID(&ChanID);
+					ChanID.IntType = ZAP_SPAN_IS_BRI(zchan->span) ? 0 : 1;		/* PRI = 1, BRI = 0 */
+					ChanID.PrefExcl = 1;	/* always exclusive in NT-mode */
+
+					if(ChanID.IntType) {
+						ChanID.InfoChanSel = 1;		/* None = 0, See Slot = 1, Any = 3 */
+						ChanID.ChanMapType = 3; 	/* B-Chan */
+						ChanID.ChanSlot = (unsigned char)zchan->chan_id;
+					} else {
+						ChanID.InfoChanSel = (unsigned char)zchan->chan_id & 0x03;	/* None = 0, B1 = 1, B2 = 2, Any = 3 */
+					}
+					gen->ChanID = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &ChanID);
+				}
+
 				Q931Rx43(&isdn_data->q931, (void *)gen, gen->Size);
 			}
 		}
 		break;
+	case ZAP_CHANNEL_STATE_DIALTONE:
+		{
+			if (!zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) {
+				if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
+					if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) {
+						zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP);
+						return;
+					}
+				}
+			}
+		}
+		break;
 	case ZAP_CHANNEL_STATE_RING:
 		{
 			if (!zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) {
@@ -769,7 +930,6 @@ static __inline__ void state_advance(zap_channel_t *zchan)
 			Q931ie_CalledNum *ptrCalledNum;
 			Q931ie_Display Display, *ptrDisplay;
 			Q931ie_HLComp HLComp;			/* High-Layer Compatibility IE */
-			Q931ie_SendComplete SComplete;		/* Sending Complete IE */
 			Q931ie_ProgInd Progress;		/* Progress Indicator IE */
 			int codec  = 0;
 
@@ -864,12 +1024,6 @@ static __inline__ void state_advance(zap_channel_t *zchan)
 			HLComp.HLCharID  = Q931_HLCHAR_TELEPHONY;	/* Telephony = 1, Fax G2+3 = 4, Fax G4 = 65 (Class I)/ 68 (Class II or III) */   /* TODO: make accessible from user layer */
 			gen->HLComp = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &HLComp);
 
-			/*
-			 * Sending complete IE (or some NT stuff waits forever in Q.931 overlap dial state...)
-			 */
-			SComplete.IEId = Q931ie_SENDING_COMPLETE;
-//			gen->SendComplete = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &SComplete);
-
 			Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
 			isdn_data->channels_local_crv[gen->CRV] = zchan;
 		}
@@ -1053,12 +1207,188 @@ static __inline__ void check_events(zap_span_t *span)
 	}
 }
 
+
+static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
+{
+	zap_buffer_t *dt_buffer = ts->user_data;
+	int wrote;
+
+	if (!dt_buffer) {
+		return -1;
+	}
+	wrote = teletone_mux_tones(ts, map);
+	zap_buffer_write(dt_buffer, ts->buffer, wrote * 2);
+	return 0;
+}
+
+static void *zap_isdn_tones_run(zap_thread_t *me, void *obj)
+{
+	zap_span_t *span = (zap_span_t *) obj;
+	zap_isdn_data_t *isdn_data = span->signal_data;
+	zap_buffer_t *dt_buffer = NULL;
+	teletone_generation_session_t ts;
+	unsigned char frame[1024];
+	zap_size_t len = sizeof(frame), rlen, blen, clen, dlen;
+	int x, interval;
+	L2ULONG t_now, t_last = zap_time_now();
+
+	memset(&ts, 0, sizeof(ts));
+
+	zap_log(ZAP_LOG_DEBUG, "ISDN tones thread starting.\n");
+
+	if (zap_buffer_create(&dt_buffer, 1024, 3192, 0) != ZAP_SUCCESS) {
+		snprintf(isdn_data->dchan->last_error, sizeof(isdn_data->dchan->last_error), "memory error!");
+		zap_log(ZAP_LOG_ERROR, "MEM ERROR\n");
+		goto done;
+	}
+
+	teletone_init_session(&ts, 0, teletone_handler, dt_buffer);
+	ts.rate = 8000;
+
+	zap_buffer_set_loops(dt_buffer, -1);
+
+	/* get a tone generation friendly interval to avoid distortions */
+	for (x = 1; x <= span->chan_count; x++) {
+		if (span->channels[x].type != ZAP_CHAN_TYPE_DQ921) {
+			zap_channel_command(&span->channels[x], ZAP_COMMAND_GET_INTERVAL, &interval);
+			break;
+		}
+	}
+	zap_log(ZAP_LOG_NOTICE, "Tone generating interval %d\n", interval);
+
+	assert(interval != 0);
+
+	while(zap_running() && zap_test_flag(isdn_data, ZAP_ISDN_RUNNING)) {
+		zap_wait_flag_t flags;
+		zap_status_t status;
+		int last_chan_state = 0;
+		int gated = 0;
+
+		/*
+		 * check b-channel states and generate & send tones if neccessary
+		 */
+		for (x = 1; x <= span->chan_count; x++) {
+			zap_channel_t *zchan = &span->channels[x];
+			zap_size_t len = sizeof(frame);
+
+			if (zchan->type == ZAP_CHAN_TYPE_DQ921) {
+				continue;
+			}
+
+			/*
+			 * Generate tones based on current bchan state
+			 * (Recycle buffer content if succeeding channels share the
+			 *  same state, this saves some cpu cycles)
+			 */
+			switch (zchan->state) {
+			case ZAP_CHANNEL_STATE_DIALTONE:
+				{
+					if (last_chan_state != zchan->state) {
+						zap_buffer_zero(dt_buffer);
+						teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_DIAL]);
+						last_chan_state = zchan->state;
+					}
+				}
+				break;
+
+			case ZAP_CHANNEL_STATE_RING:
+				{
+					if (last_chan_state != zchan->state) {
+						zap_buffer_zero(dt_buffer);
+						teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_RING]);
+						last_chan_state = zchan->state;
+					}
+				}
+				break;
+
+			default:	/* Not in a tone generating state, go to next round */
+				continue;
+			}
+
+			flags = ZAP_READ;
+
+			status = zap_channel_wait(zchan, &flags, (gated) ? 0 : interval);
+			switch(status) {
+			case ZAP_FAIL:
+				continue;
+
+			case ZAP_TIMEOUT:
+				gated = 1;
+				continue;
+
+			default:
+				if (!(flags & ZAP_READ)) {
+					continue;
+				}
+			}
+			gated = 1;
+
+			status = zap_channel_read(zchan, frame, &len);
+			if (status != ZAP_SUCCESS || len <= 0) {
+				continue;
+			}
+			clen = len;
+
+			len = ts.rate / interval;
+
+			if (zchan->effective_codec == ZAP_CODEC_SLIN) {
+				len *= 2;
+			}
+
+			rlen = zap_buffer_read_loop(dt_buffer, frame, len);
+			blen = rlen;
+
+			if (zchan->effective_codec != ZAP_CODEC_SLIN) {
+				zio_codec_t codec_func = NULL;
+
+				if (zchan->native_codec == ZAP_CODEC_ULAW) {
+					codec_func = zio_slin2ulaw;
+				} else if (zchan->native_codec == ZAP_CODEC_ALAW) {
+					codec_func = zio_slin2alaw;
+				}
+
+				if (codec_func) {
+					status = codec_func(frame, sizeof(frame), &rlen);
+					dlen = rlen;
+				} else {
+					snprintf(zchan->last_error, sizeof(zchan->last_error), "codec error!");
+					goto done;
+				}
+			}
+
+			zap_channel_write(zchan, frame, sizeof(frame), &rlen);
+			t_now = zap_time_now();
+			zap_log(ZAP_LOG_INFO, "%d - zchan %d:%d, written: %d, read: %d, encoded: %d, buffer: %d\n", (int)(t_now - t_last), zchan->span_id, zchan->chan_id, rlen, clen, dlen, blen);
+			t_last = t_now;
+		}
+
+		/*
+		 * sleep a bit if there was nothing to do
+		 */
+		if (!gated) {
+			zap_sleep(interval);
+		}
+	}
+
+done:
+	if (ts.buffer) {
+		teletone_destroy_session(&ts);
+	}
+
+	if (dt_buffer) {
+		zap_buffer_destroy(&dt_buffer);
+	}
+
+	zap_log(ZAP_LOG_DEBUG, "ISDN tone thread ended.\n");
+	return NULL;
+}
+
 static void *zap_isdn_run(zap_thread_t *me, void *obj)
 {
 	zap_span_t *span = (zap_span_t *) obj;
 	zap_isdn_data_t *isdn_data = span->signal_data;
-	unsigned char buf[1024];
-	zap_size_t len = sizeof(buf);
+	unsigned char frame[1024];
+	zap_size_t len = sizeof(frame);
 	int errs = 0;
 
 #ifdef WIN32
@@ -1078,6 +1408,9 @@ static void *zap_isdn_run(zap_thread_t *me, void *obj)
 		check_state(span);
 		check_events(span);
 
+		/*
+		 *
+		 */
 		switch(status) {
 		case ZAP_FAIL:
 			{
@@ -1098,17 +1431,17 @@ static void *zap_isdn_run(zap_thread_t *me, void *obj)
 			{
 				errs = 0;
 				if (flags & ZAP_READ) {
-					len = sizeof(buf);
-					if (zap_channel_read(isdn_data->dchan, buf, &len) == ZAP_SUCCESS) {
+					len = sizeof(frame);
+					if (zap_channel_read(isdn_data->dchan, frame, &len) == ZAP_SUCCESS) {
 #ifdef IODEBUG
 						char bb[4096] = "";
-						print_hex_bytes(buf, len, bb, sizeof(bb));
+						print_hex_bytes(frame, len, bb, sizeof(bb));
 
-						print_bits(buf, (int)len, bb, sizeof(bb), ZAP_ENDIAN_LITTLE, 0);
+						print_bits(frame, (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
 						
-						Q921QueueHDLCFrame(&isdn_data->q921, buf, (int)len);
+						Q921QueueHDLCFrame(&isdn_data->q921, frame, (int)len);
 						Q921Rx12(&isdn_data->q921);
 					}
 				} else {
@@ -1117,11 +1450,9 @@ static void *zap_isdn_run(zap_thread_t *me, void *obj)
 			}
 			break;
 		}
-
 	}
 	
  done:
-
 	zap_channel_close(&isdn_data->dchans[0]);
 	zap_channel_close(&isdn_data->dchans[1]);
 	zap_clear_flag(isdn_data, ZAP_ISDN_RUNNING);
@@ -1273,7 +1604,13 @@ static zap_state_map_t isdn_state_map = {
 			ZSD_INBOUND,
 			ZSM_UNACCEPTABLE,
 			{ZAP_CHANNEL_STATE_DOWN, ZAP_END},
-			{ZAP_CHANNEL_STATE_RING, ZAP_END}
+			{ZAP_CHANNEL_STATE_DIALTONE, ZAP_CHANNEL_STATE_RING, ZAP_END}
+		},
+		{
+			ZSD_INBOUND,
+			ZSM_UNACCEPTABLE,
+			{ZAP_CHANNEL_STATE_DIALTONE, ZAP_END},
+			{ZAP_CHANNEL_STATE_RING, ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END}
 		},
 		{
 			ZSD_INBOUND,
@@ -1312,9 +1649,20 @@ static zap_state_map_t isdn_state_map = {
 
 static zap_status_t zap_isdn_start(zap_span_t *span)
 {
+	zap_status_t ret;
+
 	zap_isdn_data_t *isdn_data = span->signal_data;
 	zap_set_flag(isdn_data, ZAP_ISDN_RUNNING);
-	return zap_thread_create_detached(zap_isdn_run, span);
+
+	ret = zap_thread_create_detached(zap_isdn_run, span);
+	if (ret != ZAP_SUCCESS) {
+		return ret;
+	}
+
+	if(ZAP_SPAN_IS_NT(span)) {
+		ret = zap_thread_create_detached(zap_isdn_tones_run, span);
+	}
+	return ret;
 }
 
 
@@ -1324,6 +1672,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_isdn_configure_span)
 	uint32_t i, x = 0;
 	zap_channel_t *dchans[2] = {0};
 	zap_isdn_data_t *isdn_data;
+	char *tonemap = "us";
 	char *var, *val;
 	Q931Dialect_t dialect = Q931_Dialect_National;
 	uint32_t opts = 0;
@@ -1385,6 +1734,11 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_isdn_configure_span)
 				break;
 			}
 			opts = isdn_data->opts = *optp;
+		} else if (!strcasecmp(var, "tonemap")) {
+			if (!(val = va_arg(ap, char *))) {
+				break;
+			}
+			tonemap = val;
 		}
 	}
 
@@ -1422,20 +1776,20 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_isdn_configure_span)
 	Q931SetLogLevel(&isdn_data->q931, Q931_LOG_DEBUG);
 
 	isdn_data->q931.autoRestartAck = 1;
-//	isdn_data->q931.autoConnectAck = 1;
 	isdn_data->q931.autoConnectAck = 0;
 	isdn_data->q931.autoServiceAck = 1;
 	span->signal_data = isdn_data;
 	span->signal_type = ZAP_SIGTYPE_ISDN;
 	span->outgoing_call = isdn_outgoing_call;
 
-
 	if ((opts & ZAP_ISDN_OPT_SUGGEST_CHANNEL)) {
 		span->channel_request = isdn_channel_request;
 		span->suggest_chan_id = 1;
 	}
 	span->state_map = &isdn_state_map;
 
+	zap_span_load_tones(span, tonemap);
+
 	return ZAP_SUCCESS;
 }
 
