Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Jul 2005 22:10:32 +0200
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        freebsd-isdn@freebsd.org
Subject:   CAPI 2.0 for passive telephony devices
Message-ID:  <200507052210.33599.hselasky@c2i.net>

next in thread | raw e-mail | index | archive | help
Hi,

I'm almost finished integrating CAPI2.0 into I4B. The CAPI interface will have 
some limitations like that it only supports HDLC and transparent mode. No 
X.75 and no FAX/Modem yet.

I have put CAPI2.0 support into /sys/dev/i4b/layer4/i4b_capidrv.c
And it's only 3000 lines long.

At the moment I am thinking about the CAPI 2.0 user library. I thought that 
the Linux way to do it could be supported too. Though I don't recommend using 
it. Then I have looked at C4B. I have decided to not go with that either, 
because things get a little complicated when having to use macros every time 
one is accesing a structure field. So I have created something new:

All CAPI structures will now be defined using a new macro 
"CAPI_MAKE_STRUCT()". Here is an example showing how to use it:

#define CH(m)\
    m(WORD, wLength,)\
    m(WORD, wApp,)\
    m(WORD, wCmd,)\
    m(WORD, wNum,)\
    m(DWORD, dwCid,)\
    m(QWORD, qwTest,)\
    m(STRUCT, sTest,)\
    m(BYTE_ARRAY, sArray, [20])\

CAPI_MAKE_STRUCT(CH);

static void
test()
{
  struct capi_message msg.
  CH_DECODED_T ch;

  u_int16_t len;

  bzero(&ch, sizeof(ch)); // clear all unused fields

  CAPI_INIT(CH, &ch); // setup tags for encoder/decoder

  ch.qwTest = 123;

  len = capi_encode(&msg, sizeof(msg), &ch);

  msg.head.wLength = htole16(len);

  capi_decode(&msg, len, &ch);
  return;
}

Here is what CAPI_MAKE_STRUCT() produces:

 typedef struct CH_DECODED { u_int8_t wLength_WORD; u_int16_t wLength;   
 u_int8_t wApp_WORD; u_int16_t wApp; u_int8_t wCmd_WORD; u_int16_t wCmd;
 u_int8_t wNum_WORD; u_int16_t wNum; u_int8_t dwCid_DWORD; u_int32_t dwCid;
 u_int8_t qwTest_QWORD; u_int64_t qwTest; u_int8_t sTest_STRUCT; 
 struct capi_struct sTest; u_int8_t sArray_BYTE_ARRAY; 
 u_int16_t sArray_BYTE_ARRAY_LENGTH; u_int8_t sArray [20]; u_int8_t CH_end; }    
 __attribute__((__packed__)) CH_DECODED_T; 

 typedef struct CH_ENCODED { u_int16_t wLength; u_int16_t wApp; 
 u_int16_t wCmd; u_int16_t wNum; u_int32_t dwCid; u_int64_t qwTest; 
 u_int8_t sTest_Null; u_int8_t sArray [20]; } 
 __attribute__((__packed__)) CH_ENCODED_T;

Here is what CAPI_INIT() produces:

 { (&ch) ->wLength_WORD = 2; (&ch) ->wApp_WORD = 2; (&ch) ->wCmd_WORD = 2;
   (&ch) ->wNum_WORD = 2; (&ch) ->dwCid_DWORD = 3; (&ch) ->qwTest_QWORD = 4;   
   (&ch) ->sTest_STRUCT = 5; (&ch) ->sArray_BYTE_ARRAY = 6; 
   (&ch) ->sTest . ie = ((void *)0); 
   (&ch) ->sArray_BYTE_ARRAY_LENGTH = sizeof(u_int8_t [20]); 
   (&ch) -> CH_end = 0; };

If one tries to use CAPI_INIT() on the wrong structure it will cause a 
compilation error!

If one enters something wrong in the definition there will most likely be a 
compilation error.


So does anyone have any objections? Else this is the way it is going to be.


--HPS



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507052210.33599.hselasky>