1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN bchannel access (for Asterisk) **
10 \*****************************************************************************/
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
29 #ifndef ISDN_PID_L2_B_USER
30 #define ISDN_PID_L2_B_USER 0x420000ff
32 #ifndef ISDN_PID_L3_B_USER
33 #define ISDN_PID_L3_B_USER 0x430000ff
36 #ifndef ISDN_PID_L4_B_USER
37 #define ISDN_PID_L4_B_USER 0x440000ff
40 /* used for udevice */
43 /* the device handler and port list */
47 /* open mISDN device */
48 void mISDNdevice_open(void)
50 /* open mISDNdevice if not already open */
56 PERROR("cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", ret, errno, strerror(errno));
60 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
64 /* close mISDN device */
65 void mISDNdevice_close(void)
70 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
74 /* create bchannel layer */
75 unsigned long mISDN_createlayer(unsigned long stid)
79 /* create new layer */
80 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel stid=0%x.\n" , stid);
81 memset(&li, 0, sizeof(li));
82 memset(&pid, 0, sizeof(pid));
86 UCPY(li.name, "B L4");
87 li.pid.layermask = ISDN_LAYER((4));
88 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
89 ret = mISDN_new_layer(mISDNdevice, &li);
93 PERROR("mISDN_new_layer() failed to add bchannel stid=0%x.\n", stid);
99 goto failed_new_layer;
101 PDEBUG(DEBUG_BCHANNEL, "new layer (addr=0x%x)\n", addr);
103 /* create new stack */
104 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
105 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
106 pid.protocol[3] = ISDN_PID_L3_B_DSP;
107 pid.protocol[4] = ISDN_PID_L4_B_USER;
108 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
109 ret = mISDN_set_stack(mISDNdevice, stid, &pid);
113 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel stid=0x%x\n", ret, stid);
114 mISDN_write_frame(mISDNdevice, buff, addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
117 ret = mISDN_get_setstack_ind(mISDNdevice, addr);
122 addr = mISDN_get_layerid(mISDNdevice, stid, 4);
127 /* destroy bchannel layer */
128 void mISDN_destroylayer(unsigned long stid, unsigned long addr)
130 /* remove our stack only if set */
133 PDEBUG(DEBUG_BCHANNEL, "free stack (addr=0x%x)\n", addr);
134 mISDN_clear_stack(mISDNdevice, stid);
135 mISDN_write_frame(mISDNdevice, buff, addr | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
139 /* do activation and deactivation of bchannel */
140 static void mISDN_bchannelactivate(unsigned long addr, int activate)
144 /* activate bchannel */
145 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
146 act.addr = addr | FLG_MSG_DOWN;
149 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
152 /* handle all mISDN messages */
153 int mISDN_handler(void)
158 struct mISDNport *mISDNport;
159 class PmISDN *isdnport;
162 mISDNuser_head_t *hh;
165 /* no device, no read */
169 /* get message from kernel */
170 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
172 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
178 FATAL("Failed to do mISDN_read()\n");
183 // printf("%s: ERROR: mISDN_read() returns nothing\n");
187 frm = (iframe_t *)msg->data;
192 case MGR_DELLAYER | CONFIRM:
193 case MGR_INITTIMER | CONFIRM:
194 case MGR_ADDTIMER | CONFIRM:
195 case MGR_DELTIMER | CONFIRM:
196 case MGR_REMOVETIMER | CONFIRM:
201 /* look for channel instance, that has the address of this message */
205 if (frm->addr == chan->b_addr)
211 PERROR("message belongs to no chan: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
218 /* we don't care about confirms, we use rx data to sync tx */
219 case PH_DATA | CONFIRM:
220 case DL_DATA | CONFIRM:
223 /* we receive audio data, we respond to it AND we send tones */
224 case PH_DATA | INDICATION:
225 case DL_DATA | INDICATION:
226 case PH_CONTROL | INDICATION:
228 chan->bchannel_receive(frm);
231 case PH_ACTIVATE | INDICATION:
232 case DL_ESTABLISH | INDICATION:
233 case PH_ACTIVATE | CONFIRM:
234 case DL_ESTABLISH | CONFIRM:
235 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
237 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
240 case PH_DEACTIVATE | INDICATION:
241 case DL_RELEASE | INDICATION:
242 case PH_DEACTIVATE | CONFIRM:
243 case DL_RELEASE | CONFIRM:
244 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
246 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
250 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);