From 7c17b9c136f082c898ee65dda897b42c8449b6d7 Mon Sep 17 00:00:00 2001
From: Michael Jerris <mike@jerris.com>
Date: Mon, 28 May 2007 22:48:13 +0000
Subject: [PATCH] Start of support for codesets and shift operation in
 messages.

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@170 a93c3328-9c30-0410-af19-c9cd2b2d52af
---
 libs/freetdm/src/isdn/Q931.c           |  3 ++
 libs/freetdm/src/isdn/Q931ie.c         | 63 ++++++++++++++++++++++++++
 libs/freetdm/src/isdn/include/Q931.h   |  1 +
 libs/freetdm/src/isdn/include/Q931ie.h |  4 +-
 libs/freetdm/src/isdn/nationalmes.c    | 18 ++++++--
 5 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/libs/freetdm/src/isdn/Q931.c b/libs/freetdm/src/isdn/Q931.c
index d522db0cc4..29fff86284 100644
--- a/libs/freetdm/src/isdn/Q931.c
+++ b/libs/freetdm/src/isdn/Q931.c
@@ -334,6 +334,9 @@ L3INT Q931Rx23(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT Size)
     /* Message Type */
     m->MesType = Mes[IOff++];
 
+    /* Starting Codeset */
+	m->codeset = Q931_CODESET_0;
+
     /* Call table proc to unpack codec message */
 	RetCode = Q931Umes[pTrunk->Dialect][m->MesType](pTrunk, Mes, (Q931mes_Generic *)pTrunk->L3Buf, Q931L4HeaderSpace + IOff , Size - Q931L4HeaderSpace - IOff + 1);
 
diff --git a/libs/freetdm/src/isdn/Q931ie.c b/libs/freetdm/src/isdn/Q931ie.c
index 87069633c3..75531cad82 100644
--- a/libs/freetdm/src/isdn/Q931ie.c
+++ b/libs/freetdm/src/isdn/Q931ie.c
@@ -2977,3 +2977,66 @@ L3INT Q931Pie_UserUser(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L
     return rc;
 }
 
+/*****************************************************************************
+
+  Function:     Q931Uie_GenericDigits
+
+  Parameters:   pIE[OUT]        ptr to Information Element id.
+                IBuf[IN]        ptr to a packed ie.
+                OBuf[OUT]       ptr to buffer for Unpacked ie.
+                IOff[IN\OUT]    Input buffer offset
+                OOff[IN\OUT]    Output buffer offset
+
+
+                Ibuf and OBuf points directly to buffers. The IOff and OOff
+                must be updated, but are otherwise not used in the ie unpack.
+
+  Return Value: Error Message
+
+*****************************************************************************/
+L3INT Q931Uie_GenericDigits(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
+{
+    Q931ie_GenericDigits * pie = (Q931ie_GenericDigits*)OBuf;
+	ie *pIE = &pMsg->GenericDigits;
+    L3INT Off = 0;
+    L3INT Octet = 0;
+    L3INT x=0;
+    L3INT IESize;
+
+    *pIE=0;
+
+    /* Octet 1 */
+    pie->IEId        = IBuf[Octet++];
+
+    /* Octet 2 */
+    IESize = IBuf[Octet++]; 
+
+    Q931SetIE(*pIE, *OOff);
+
+	*IOff = (*IOff) + Octet + Off;
+    *OOff = (*OOff) + sizeof(Q931ie_GenericDigits) + x -1;
+    
+	pie->Size = (L3UCHAR)(sizeof(Q931ie_GenericDigits) + x -1);
+
+    return Q931E_NO_ERROR;
+}
+
+/*****************************************************************************
+
+  Function:     Q931Pie_GenericDigits
+
+  Parameters:   IBuf[IN]        Ptr to struct.
+                OBuf[OUT]        Ptr tp packed output buffer.
+                Octet[IN/OUT]    Offset into OBuf.
+
+  Return Value:    Error code, 0 = OK
+
+*****************************************************************************/
+
+L3INT Q931Pie_GenericDigits(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
+{
+	OBuf[(*Octet)++] = (Q931ie_GENERIC_DIGITS & 0xFF);
+    OBuf[(*Octet)++] = 2;
+
+    return Q931E_NO_ERROR;
+}
diff --git a/libs/freetdm/src/isdn/include/Q931.h b/libs/freetdm/src/isdn/include/Q931.h
index 6c580d8bb6..346460a2ba 100644
--- a/libs/freetdm/src/isdn/include/Q931.h
+++ b/libs/freetdm/src/isdn/include/Q931.h
@@ -420,6 +420,7 @@ typedef struct
 	ie				Switchhook;
 	ie				FeatAct;
 	ie				FeatInd;
+	ie				GenericDigits;
 
 	L3UCHAR			buf[1];			/* Buffer for IE's						*/
 
diff --git a/libs/freetdm/src/isdn/include/Q931ie.h b/libs/freetdm/src/isdn/include/Q931ie.h
index 27e292d1f9..76633e1882 100644
--- a/libs/freetdm/src/isdn/include/Q931ie.h
+++ b/libs/freetdm/src/isdn/include/Q931ie.h
@@ -96,7 +96,9 @@ typedef enum {
 #define Q931ie_USER_USER                        0x7e /* 0111 1110       */
 #define Q931ie_ESCAPE_FOR_EX                    0x7f /* 0111 1111       */
 
-#define Q931ie_GENERIC_DIGITS               0x37 /* 0011 0111       */
+/* Variable Length Codeset 6 Information Elements */
+
+#define Q931ie_GENERIC_DIGITS  Q931_CODESET_6 | 0x37 /* 0011 0111       */
 
 
 
diff --git a/libs/freetdm/src/isdn/nationalmes.c b/libs/freetdm/src/isdn/nationalmes.c
index b256a318d6..a0b4f195bd 100644
--- a/libs/freetdm/src/isdn/nationalmes.c
+++ b/libs/freetdm/src/isdn/nationalmes.c
@@ -56,10 +56,22 @@ L3INT nationalUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generi
 	L3INT ir=0;
 	L3INT OOff=0;
 	L3INT rc=Q931E_NO_ERROR;
+	L3UINT last_codeset = mes->codeset;
+	L3UCHAR shift_lock = 1;
 
 	while(IOff < Size)
 	{
-		switch(IBuf[IOff])
+		if (!shift_lock) {
+			mes->codeset = last_codeset;
+		}
+
+		if ((IBuf[IOff] & 0xF0) == Q931ie_SHIFT ) {
+			mes->codeset = ((IBuf[IOff] & 0x07) << 8);
+			shift_lock = (IBuf[IOff] & 0x08);
+			IOff++;
+		}
+
+		switch(mes->codeset | IBuf[IOff])
 		{
 		case Q931ie_SENDING_COMPLETE:
 		case Q931ie_BEARER_CAPABILITY:
@@ -93,10 +105,6 @@ L3INT nationalUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generi
 			/* TODO: Implement this ie */
 			IOff = IOff + 4;
 			break;
-		case Q931ie_SHIFT:
-			/* TODO: Implement this ie */
-			IOff++;
-			break;
 		default:
 			return Q931E_ILLEGAL_IE;
 			break;