Merge branch 'develop'
[lcr.git] / gsm.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** LCR                                                                       **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** mISDN gsm                                                                 **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13
14 #ifndef _GNU_SOURCE
15 #define _GNU_SOURCE
16 #endif
17 extern "C" {
18 #include <getopt.h>
19
20 #include <openbsc/db.h>
21 #include <osmocore/select.h>
22 #include <openbsc/debug.h>
23 #include <openbsc/e1_input.h>
24 #include <osmocore/talloc.h>
25 #include <openbsc/mncc.h>
26 #include <openbsc/trau_frame.h>
27 struct gsm_network *bsc_gsmnet = 0;
28 extern int ipacc_rtp_direct;
29 extern int bsc_bootstrap_network(int (*mmc_rev)(struct gsm_network *, int, void *),
30                                  const char *cfg_file);
31 extern int bsc_shutdown_net(struct gsm_network *net);
32 void talloc_ctx_init(void);
33 void on_dso_load_token(void);
34 void on_dso_load_rrlp(void);
35 void on_dso_load_ho_dec(void);
36 int bts_model_unknown_init(void);
37 int bts_model_bs11_init(void);
38 int bts_model_nanobts_init(void);
39 static struct debug_target *stderr_target;
40
41 /* timer to store statistics */
42 #define DB_SYNC_INTERVAL        60, 0
43 static struct timer_list db_sync_timer;
44
45 #include "gsm_audio.h"
46
47 }
48
49 #include <mISDN/mISDNcompat.h>
50
51 struct lcr_gsm *gsm = NULL;
52
53 static unsigned int new_callref = 1;
54
55 /* timer handling */
56 static int _db_store_counter(struct counter *counter, void *data)
57 {
58         return db_store_counter(counter);
59 }
60
61 static void db_sync_timer_cb(void *data)
62 {
63         /* store counters to database and re-schedule */
64         counters_for_each(_db_store_counter, NULL);
65         bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
66 }
67
68 /*
69  * create and send mncc message
70  */
71 static struct gsm_mncc *create_mncc(int msg_type, unsigned int callref)
72 {
73         struct gsm_mncc *mncc;
74
75         mncc = (struct gsm_mncc *)MALLOC(sizeof(struct gsm_mncc));
76         mncc->msg_type = msg_type;
77         mncc->callref = callref;
78         return (mncc);
79 }
80 static int send_and_free_mncc(struct gsm_network *net, unsigned int msg_type, void *data)
81 {
82         int ret;
83
84         ret = mncc_send(net, msg_type, data);
85         free(data);
86
87         return ret;
88 }
89
90 static int delete_event(struct lcr_work *work, void *instance, int index);
91
92 /*
93  * constructor
94  */
95 Pgsm::Pgsm(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, channel, exclusive, mode)
96 {
97         p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
98         memset(&p_m_g_delete, 0, sizeof(p_m_g_delete));
99         add_work(&p_m_g_delete, delete_event, this, 0);
100         p_m_g_callref = 0;
101         p_m_g_mode = 0;
102         p_m_g_gsm_b_sock = -1;
103         p_m_g_gsm_b_index = -1;
104         p_m_g_gsm_b_active = 0;
105         p_m_g_notify_pending = NULL;
106         p_m_g_decoder = gsm_audio_create();
107         p_m_g_encoder = gsm_audio_create();
108         if (!p_m_g_encoder || !p_m_g_decoder) {
109                 PERROR("Failed to create GSM audio codec instance\n");
110                 trigger_work(&p_m_g_delete);
111         }
112         p_m_g_rxpos = 0;
113         p_m_g_tch_connected = 0;
114
115         PDEBUG(DEBUG_GSM, "Created new mISDNPort(%s).\n", portname);
116 }
117
118 /*
119  * destructor
120  */
121 Pgsm::~Pgsm()
122 {
123         PDEBUG(DEBUG_GSM, "Destroyed GSM process(%s).\n", p_name);
124
125         del_work(&p_m_g_delete);
126
127         /* remove queued message */
128         if (p_m_g_notify_pending)
129                 message_free(p_m_g_notify_pending);
130
131         /* close audio transfer socket */
132         if (p_m_g_gsm_b_sock > -1)
133                 bchannel_close();
134
135         /* close codec */
136         if (p_m_g_encoder)
137                 gsm_audio_destroy(p_m_g_encoder);
138         if (p_m_g_decoder)
139                 gsm_audio_destroy(p_m_g_decoder);
140 }
141
142
143 /* close bsc side bchannel */
144 void Pgsm::bchannel_close(void)
145 {
146         if (p_m_g_gsm_b_sock > -1) {
147                 unregister_fd(&p_m_g_gsm_b_fd);
148                 close(p_m_g_gsm_b_sock);
149         }
150         p_m_g_gsm_b_sock = -1;
151         p_m_g_gsm_b_index = -1;
152         p_m_g_gsm_b_active = 0;
153 }
154
155 static int b_handler(struct lcr_fd *fd, unsigned int what, void *instance, int index);
156
157 /* open bsc side bchannel */
158 int Pgsm::bchannel_open(int index)
159 {
160         int ret;
161         struct sockaddr_mISDN addr;
162         struct mISDNhead act;
163
164         if (p_m_g_gsm_b_sock > -1) {
165                 PERROR("Socket already created for index %d\n", index);
166                 return(-EIO);
167         }
168
169         /* open socket */
170         ret = p_m_g_gsm_b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW);
171         if (ret < 0) {
172                 PERROR("Failed to open bchannel-socket for index %d\n", index);
173                 bchannel_close();
174                 return(ret);
175         }
176         memset(&p_m_g_gsm_b_fd, 0, sizeof(p_m_g_gsm_b_fd));
177         p_m_g_gsm_b_fd.fd = p_m_g_gsm_b_sock;
178         register_fd(&p_m_g_gsm_b_fd, LCR_FD_READ, b_handler, this, 0);
179
180
181         /* bind socket to bchannel */
182         addr.family = AF_ISDN;
183         addr.dev = gsm->gsm_port;
184         addr.channel = index+1+(index>15);
185         ret = bind(p_m_g_gsm_b_sock, (struct sockaddr *)&addr, sizeof(addr));
186         if (ret < 0) {
187                 PERROR("Failed to bind bchannel-socket for index %d\n", index);
188                 bchannel_close();
189                 return(ret);
190         }
191         /* activate bchannel */
192         PDEBUG(DEBUG_GSM, "Activating GSM side channel index %i.\n", index);
193         act.prim = PH_ACTIVATE_REQ; 
194         act.id = 0;
195         ret = sendto(p_m_g_gsm_b_sock, &act, MISDN_HEADER_LEN, 0, NULL, 0);
196         if (ret < 0) {
197                 PERROR("Failed to activate index %d\n", index);
198                 bchannel_close();
199                 return(ret);
200         }
201
202         p_m_g_gsm_b_index = index;
203
204         return(0);
205 }
206
207 /* receive from bchannel */
208 void Pgsm::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
209 {
210         unsigned char frame[33];
211
212         /* encoder init failed */
213         if (!p_m_g_encoder)
214                 return;
215
216         /* (currently) not connected, so don't flood tch! */
217         if (!p_m_g_tch_connected)
218                 return;
219
220         /* write to rx buffer */
221         while(len--) {
222                 p_m_g_rxdata[p_m_g_rxpos++] = audio_law_to_s32[*data++];
223                 if (p_m_g_rxpos == 160) {
224                         p_m_g_rxpos = 0;
225
226                         /* encode data */
227                         gsm_audio_encode(p_m_g_encoder, p_m_g_rxdata, frame);
228                         frame_send(frame);
229                 }
230         }
231 }
232
233 /* transmit to bchannel */
234 void Pgsm::bchannel_send(unsigned int prim, unsigned int id, unsigned char *data, int len)
235 {
236         unsigned char buf[MISDN_HEADER_LEN+len];
237         struct mISDNhead *hh = (struct mISDNhead *)buf;
238         int ret;
239
240         if (!p_m_g_gsm_b_active)
241                 return;
242
243         /* make and send frame */
244         hh->prim = PH_DATA_REQ;
245         hh->id = 0;
246         memcpy(buf+MISDN_HEADER_LEN, data, len);
247         ret = sendto(p_m_g_gsm_b_sock, buf, MISDN_HEADER_LEN+len, 0, NULL, 0);
248         if (ret <= 0)
249                 PERROR("Failed to send to socket index %d\n", index);
250 }
251
252 void Pgsm::frame_send(void *_frame)
253 {
254         unsigned char buffer[sizeof(struct gsm_data_frame) + 33];
255         struct gsm_data_frame *frame = (struct gsm_data_frame *)buffer;
256         
257         frame->msg_type = GSM_TCHF_FRAME;
258         frame->callref = p_m_g_callref;
259         memcpy(frame->data, _frame, 33);
260         mncc_send((struct gsm_network *)gsm->network, frame->msg_type, frame);
261 }
262
263
264 void Pgsm::frame_receive(void *_frame)
265 {
266         struct gsm_data_frame *frame = (struct gsm_data_frame *)_frame;
267         signed short samples[160];
268         unsigned char data[160];
269         int i;
270
271         if (!p_m_g_decoder)
272                 return;
273
274         if ((frame->data[0]>>4) != 0xd)
275                 PERROR("received GSM frame with wrong magig 0x%x\n", frame->data[0]>>4);
276         
277         /* decode */
278         gsm_audio_decode(p_m_g_decoder, frame->data, samples);
279         for (i = 0; i < 160; i++) {
280                 data[i] = audio_s16_to_law[samples[i] & 0xffff];
281         }
282
283         /* send */
284         bchannel_send(PH_DATA_REQ, 0, data, 160);
285 }
286
287
288 /*
289  * create trace
290  **/
291 static void gsm_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg_type, int direction)
292 {
293         char msgtext[64];
294
295         /* select message and primitive text */
296         SCPY(msgtext, get_mncc_name(msg_type));
297
298         /* add direction */
299         if (direction == DIRECTION_OUT)
300                 SCAT(msgtext, " MSC->BSC");
301         else
302                 SCAT(msgtext, " MSC<-BSC");
303
304         /* init trace with given values */
305         start_trace(mISDNport?mISDNport->portnum:-1,
306                     mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
307                     port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
308                     port?port->p_dialinginfo.id:NULL,
309                     direction,
310                     CATEGORY_CH,
311                     port?port->p_serial:0,
312                     msgtext);
313 }
314
315
316
317 /* select bchannel */
318 int Pgsm::hunt_bchannel(void)
319 {
320         int channel;
321         int i;
322
323         chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (setup)", DIRECTION_NONE);
324         add_trace("channel", "reserved", "%d", p_m_mISDNport->b_reserved);
325         if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num) { // of out chan..
326                 add_trace("conclusion", NULL, "all channels are reserved");
327                 end_trace();
328                 return(-34); // no channel
329         }
330         /* find channel */
331         i = 0;
332         channel = 0;
333         while(i < p_m_mISDNport->b_num) {
334                 if (p_m_mISDNport->b_port[i] == NULL) {
335                         channel = i+1+(i>=15);
336                         break;
337                 }
338                 i++;
339         }
340         if (!channel) {
341                 add_trace("conclusion", NULL, "no channel available");
342                 end_trace();
343                 return(-6); // channel unacceptable
344         }
345         add_trace("conclusion", NULL, "channel available");
346         add_trace("connect", "channel", "%d", channel);
347         end_trace();
348         return(channel);
349 }
350
351
352 /*
353  * handles all indications
354  */
355 /* SETUP INDICATION */
356 void Pgsm::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
357 {
358         int ret;
359         class Endpoint *epoint;
360         struct lcr_msg *message;
361         int channel;
362         struct gsm_mncc *mode, *proceeding, *frame;
363
364         /* emergency shutdown */
365         printf("%d %d\n", mncc->emergency, !gsm->conf.noemergshut);
366         if (mncc->emergency && !gsm->conf.noemergshut) {
367                 start_trace(p_m_mISDNport->portnum,
368                         p_m_mISDNport->ifport->interface,
369                         NULL,
370                         NULL,
371                         DIRECTION_NONE,
372                         CATEGORY_CH,
373                         0,
374                         "EMERGENCY SHUTDOWN (due to received emergency call)");
375                 end_trace();
376                 quit = 1;
377         }
378         /* process given callref */
379         l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_L3ID_IND, DIRECTION_IN);
380         add_trace("callref", "new", "0x%x", callref);
381         if (p_m_g_callref) {
382                 /* release in case the ID is already in use */
383                 add_trace("error", NULL, "callref already in use");
384                 end_trace();
385                 mncc = create_mncc(MNCC_REJ_REQ, callref);
386                 gsm_trace_header(p_m_mISDNport, this, MNCC_REJ_REQ, DIRECTION_OUT);
387                 mncc->fields |= MNCC_F_CAUSE;
388                 mncc->cause.coding = 3;
389                 mncc->cause.location = 1;
390                 mncc->cause.value = 47;
391                 add_trace("cause", "coding", "%d", mncc->cause.coding);
392                 add_trace("cause", "location", "%d", mncc->cause.location);
393                 add_trace("cause", "value", "%d", mncc->cause.value);
394                 add_trace("reason", NULL, "callref already in use");
395                 end_trace();
396                 send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
397                 new_state(PORT_STATE_RELEASE);
398                 trigger_work(&p_m_g_delete);
399                 return;
400         }
401         p_m_g_callref = callref;
402         end_trace();
403
404         /* if blocked, release call with MT_RELEASE_COMPLETE */
405         if (p_m_mISDNport->ifport->block) {
406                 mncc = create_mncc(MNCC_REJ_REQ, p_m_g_callref);
407                 gsm_trace_header(p_m_mISDNport, this, MNCC_REJ_REQ, DIRECTION_OUT);
408                 mncc->fields |= MNCC_F_CAUSE;
409                 mncc->cause.coding = 3;
410                 mncc->cause.location = 1;
411                 mncc->cause.value = 27;
412                 add_trace("cause", "coding", "%d", mncc->cause.coding);
413                 add_trace("cause", "location", "%d", mncc->cause.location);
414                 add_trace("cause", "value", "%d", mncc->cause.value);
415                 add_trace("reason", NULL, "port is blocked");
416                 end_trace();
417                 send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
418                 new_state(PORT_STATE_RELEASE);
419                 trigger_work(&p_m_g_delete);
420                 return;
421         }
422
423         /* caller info */
424         if (mncc->clir.inv)
425                 p_callerinfo.present = INFO_PRESENT_RESTRICTED;
426         else
427                 p_callerinfo.present = INFO_PRESENT_ALLOWED;
428         if (mncc->calling.number[0])
429                 SCPY(p_callerinfo.id, mncc->calling.number);
430         else
431                 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
432         SCPY(p_callerinfo.imsi, mncc->imsi);
433         p_callerinfo.screen = INFO_SCREEN_NETWORK;
434         p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
435         p_callerinfo.isdn_port = p_m_portnum;
436         SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
437
438         /* dialing information */
439         SCAT(p_dialinginfo.id, mncc->called.number);
440         switch (mncc->called.type) {
441                 case 0x1:
442                 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
443                 break;
444                 case 0x2:
445                 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
446                 break;
447                 case 0x4:
448                 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
449                 break;
450                 default:
451                 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
452                 break;
453         }
454         if (mncc->emergency) {
455                 SCPY(p_dialinginfo.id, "emergency");
456         }
457         p_dialinginfo.sending_complete = 1;
458
459         /* bearer capability */
460         // todo
461         p_capainfo.bearer_capa = INFO_BC_SPEECH;
462         p_capainfo.bearer_info1 = (options.law=='a')?3:2;
463         p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
464         p_capainfo.source_mode = B_MODE_TRANSPARENT;
465         p_m_g_mode = p_capainfo.source_mode;
466
467         /* useruser */
468
469         /* hunt channel */
470         ret = channel = hunt_bchannel();
471         if (ret < 0)
472                 goto no_channel;
473
474         /* open channel */
475         ret = seize_bchannel(channel, 1);
476         if (ret < 0) {
477                 no_channel:
478                 mncc = create_mncc(MNCC_REJ_REQ, p_m_g_callref);
479                 gsm_trace_header(p_m_mISDNport, this, MNCC_REJ_REQ, DIRECTION_OUT);
480                 mncc->fields |= MNCC_F_CAUSE;
481                 mncc->cause.coding = 3;
482                 mncc->cause.location = 1;
483                 mncc->cause.value = 34;
484                 add_trace("cause", "coding", "%d", mncc->cause.coding);
485                 add_trace("cause", "location", "%d", mncc->cause.location);
486                 add_trace("cause", "value", "%d", mncc->cause.value);
487                 add_trace("reason", NULL, "no channel");
488                 end_trace();
489                 send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
490                 new_state(PORT_STATE_RELEASE);
491                 trigger_work(&p_m_g_delete);
492                 return;
493         }
494         bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
495         if (bchannel_open(p_m_b_index))
496                 goto no_channel;
497
498         /* what infos did we got ... */
499         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
500         if (p_callerinfo.id[0])
501                 add_trace("calling", "number", "%s", p_callerinfo.id);
502         else
503                 SPRINT(p_callerinfo.id, "imsi-%s", p_callerinfo.imsi);
504         add_trace("calling", "imsi", "%s", p_callerinfo.imsi);
505         add_trace("dialing", "number", "%s", p_dialinginfo.id);
506         end_trace();
507
508         /* create endpoint */
509         if (p_epointlist)
510                 FATAL("Incoming call but already got an endpoint.\n");
511         if (!(epoint = new Endpoint(p_serial, 0)))
512                 FATAL("No memory for Endpoint instance\n");
513         if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming
514                 FATAL("No memory for Endpoint Application instance\n");
515         epointlist_new(epoint->ep_serial);
516
517         /* modify lchan to GSM codec V1 */
518         gsm_trace_header(p_m_mISDNport, this, MNCC_LCHAN_MODIFY, DIRECTION_OUT);
519         mode = create_mncc(MNCC_LCHAN_MODIFY, p_m_g_callref);
520         mode->lchan_mode = 0x01; /* GSM V1 */
521         add_trace("mode", NULL, "0x%02x", mode->lchan_mode);
522         end_trace();
523         send_and_free_mncc((struct gsm_network *)gsm->network, mode->msg_type, mode);
524
525         /* send call proceeding */
526         gsm_trace_header(p_m_mISDNport, this, MNCC_CALL_PROC_REQ, DIRECTION_OUT);
527         proceeding = create_mncc(MNCC_CALL_PROC_REQ, p_m_g_callref);
528         if (p_m_mISDNport->tones) {
529                 proceeding->fields |= MNCC_F_PROGRESS;
530                 proceeding->progress.coding = 3; /* GSM */
531                 proceeding->progress.location = 1;
532                 proceeding->progress.descr = 8;
533                 add_trace("progress", "coding", "%d", proceeding->progress.coding);
534                 add_trace("progress", "location", "%d", proceeding->progress.location);
535                 add_trace("progress", "descr", "%d", proceeding->progress.descr);
536         }
537         end_trace();
538         send_and_free_mncc((struct gsm_network *)gsm->network, proceeding->msg_type, proceeding);
539
540         new_state(PORT_STATE_IN_PROCEEDING);
541
542         if (p_m_mISDNport->tones && !p_m_g_tch_connected) { /* only if ... */
543                 gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
544                 end_trace();
545                 frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
546                 send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
547                 p_m_g_tch_connected = 1;
548         }
549
550         /* send setup message to endpoit */
551         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
552         message->param.setup.isdn_port = p_m_portnum;
553         message->param.setup.port_type = p_type;
554 //      message->param.setup.dtmf = 0;
555         memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
556         memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
557         memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
558         SCPY((char *)message->param.setup.useruser.data, (char *)mncc->useruser.info);
559         message->param.setup.useruser.len = strlen(mncc->useruser.info);
560         message->param.setup.useruser.protocol = mncc->useruser.proto;
561         message_put(message);
562 }
563
564 /* DTMF INDICATION */
565 void Pgsm::start_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
566 {
567         struct lcr_msg *message;
568         struct gsm_mncc *resp;
569
570         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
571         add_trace("keypad", NULL, "%c", mncc->keypad);
572         end_trace();
573         SPRINT(p_dialinginfo.id, "%c", mncc->keypad);
574         p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
575
576         /* send resp */
577         gsm_trace_header(p_m_mISDNport, this, MNCC_START_DTMF_RSP, DIRECTION_OUT);
578         add_trace("keypad", NULL, "%c", mncc->keypad);
579         end_trace();
580         resp = create_mncc(MNCC_START_DTMF_RSP, p_m_g_callref);
581         resp->keypad = mncc->keypad;
582         send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
583
584         /* send dialing information */
585         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
586         memcpy(&message->param.information, &p_dialinginfo, sizeof(struct dialing_info));
587         message_put(message);
588 }
589 void Pgsm::stop_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
590 {
591         struct gsm_mncc *resp;
592
593         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
594         add_trace("keypad", NULL, "%c", mncc->keypad);
595         end_trace();
596
597         /* send resp */
598         gsm_trace_header(p_m_mISDNport, this, MNCC_STOP_DTMF_RSP, DIRECTION_OUT);
599         add_trace("keypad", NULL, "%c", mncc->keypad);
600         end_trace();
601         resp = create_mncc(MNCC_STOP_DTMF_RSP, p_m_g_callref);
602         resp->keypad = mncc->keypad;
603         send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
604 }
605
606 /* PROCEEDING INDICATION */
607 void Pgsm::call_conf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
608 {
609         struct gsm_mncc *mode;
610
611         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
612         if (mncc->fields & MNCC_F_CAUSE) {
613                 add_trace("cause", "coding", "%d", mncc->cause.coding);
614                 add_trace("cause", "location", "%", mncc->cause.location);
615                 add_trace("cause", "value", "%", mncc->cause.value);
616         }
617         end_trace();
618
619         /* modify lchan to GSM codec V1 */
620         gsm_trace_header(p_m_mISDNport, this, MNCC_LCHAN_MODIFY, DIRECTION_OUT);
621         mode = create_mncc(MNCC_LCHAN_MODIFY, p_m_g_callref);
622         mode->lchan_mode = 0x01; /* GSM V1 */
623         add_trace("mode", NULL, "0x%02x", mode->lchan_mode);
624         end_trace();
625         send_and_free_mncc((struct gsm_network *)gsm->network, mode->msg_type, mode);
626
627 }
628
629 /* ALERTING INDICATION */
630 void Pgsm::alert_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
631 {
632         struct lcr_msg *message;
633
634         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
635         end_trace();
636
637         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_ALERTING);
638         message_put(message);
639
640         new_state(PORT_STATE_OUT_ALERTING);
641
642 }
643
644 /* CONNECT INDICATION */
645 void Pgsm::setup_cnf(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
646 {
647         struct gsm_mncc *resp, *frame;
648         struct lcr_msg *message;
649
650         SCPY(p_connectinfo.id, mncc->connected.number);
651         SCPY(p_connectinfo.imsi, mncc->imsi);
652         p_connectinfo.present = INFO_PRESENT_ALLOWED;
653         p_connectinfo.screen = INFO_SCREEN_NETWORK;
654         p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
655         p_connectinfo.isdn_port = p_m_portnum;
656         SCPY(p_connectinfo.interface, p_m_mISDNport->ifport->interface->name);
657
658         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
659         if (p_connectinfo.id[0])
660                 add_trace("connect", "number", "%s", p_connectinfo.id);
661         else if (mncc->imsi[0])
662                 SPRINT(p_connectinfo.id, "imsi-%s", p_connectinfo.imsi);
663         if (mncc->imsi[0])
664                 add_trace("connect", "imsi", "%s", p_connectinfo.imsi);
665         end_trace();
666
667         /* send resp */
668         gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_COMPL_REQ, DIRECTION_OUT);
669         resp = create_mncc(MNCC_SETUP_COMPL_REQ, p_m_g_callref);
670         end_trace();
671         send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
672
673         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
674         memcpy(&message->param.connectinfo, &p_connectinfo, sizeof(struct connect_info));
675         message_put(message);
676
677         new_state(PORT_STATE_CONNECT);
678
679         if (!p_m_g_tch_connected) { /* only if ... */
680                 gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
681                 end_trace();
682                 frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
683                 send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
684                 p_m_g_tch_connected = 1;
685         }
686 }
687
688 /* CONNECT ACK INDICATION */
689 void Pgsm::setup_compl_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
690 {
691         struct gsm_mncc *frame;
692
693         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
694         end_trace();
695
696         new_state(PORT_STATE_CONNECT);
697
698         if (!p_m_g_tch_connected) { /* only if ... */
699                 gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
700                 end_trace();
701                 frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
702                 send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
703                 p_m_g_tch_connected = 1;
704         }
705 }
706
707 /* DISCONNECT INDICATION */
708 void Pgsm::disc_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
709 {
710         struct lcr_msg *message;
711         int cause = 16, location = 0;
712         struct gsm_mncc *resp;
713
714         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
715         if (mncc->fields & MNCC_F_CAUSE) {
716                 location = mncc->cause.location;
717                 cause = mncc->cause.value;
718                 add_trace("cause", "coding", "%d", mncc->cause.coding);
719                 add_trace("cause", "location", "%d", location);
720                 add_trace("cause", "value", "%d", cause);
721         }
722         end_trace();
723
724         /* send release */
725         resp = create_mncc(MNCC_REL_REQ, p_m_g_callref);
726         gsm_trace_header(p_m_mISDNport, this, MNCC_REL_REQ, DIRECTION_OUT);
727 #if 0
728         resp->fields |= MNCC_F_CAUSE;
729         resp->cause.coding = 3;
730         resp->cause.location = 1;
731         resp->cause.value = cause;
732         add_trace("cause", "coding", "%d", resp->cause.coding);
733         add_trace("cause", "location", "%d", resp->cause.location);
734         add_trace("cause", "value", "%d", resp->cause.value);
735 #endif
736         end_trace();
737         send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
738
739         /* sending release to endpoint */
740         while(p_epointlist) {
741                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
742                 message->param.disconnectinfo.cause = cause;
743                 message->param.disconnectinfo.location = location;
744                 message_put(message);
745                 /* remove epoint */
746                 free_epointlist(p_epointlist);
747         }
748         new_state(PORT_STATE_RELEASE);
749         trigger_work(&p_m_g_delete);
750 }
751
752 /* CC_RELEASE INDICATION */
753 void Pgsm::rel_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
754 {
755         int location = 0, cause = 16;
756         struct lcr_msg *message;
757
758         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
759         if (mncc->fields & MNCC_F_CAUSE) {
760                 location = mncc->cause.location;
761                 cause = mncc->cause.value;
762                 add_trace("cause", "coding", "%d", mncc->cause.coding);
763                 add_trace("cause", "location", "%d", mncc->cause.location);
764                 add_trace("cause", "value", "%d", mncc->cause.value);
765         }
766         end_trace();
767
768         /* sending release to endpoint */
769         while(p_epointlist) {
770                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
771                 message->param.disconnectinfo.cause = cause;
772                 message->param.disconnectinfo.location = location;
773                 message_put(message);
774                 /* remove epoint */
775                 free_epointlist(p_epointlist);
776         }
777         new_state(PORT_STATE_RELEASE);
778         trigger_work(&p_m_g_delete);
779 }
780
781 /* NOTIFY INDICATION */
782 void Pgsm::notify_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
783 {
784         struct lcr_msg *message;
785
786         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
787         add_trace("notify", NULL, "%d", mncc->notify);
788         end_trace();
789
790         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
791         message->param.notifyinfo.notify = mncc->notify;
792         message_put(message);
793 }
794
795
796 /* HOLD INDICATION */
797 void Pgsm::hold_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
798 {
799         struct lcr_msg *message;
800         struct gsm_mncc *resp, *frame;
801
802         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
803         end_trace();
804
805         /* notify the hold of call */
806         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
807         message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
808         message->param.notifyinfo.local = 1; /* call is held by supplementary service */
809         message_put(message);
810
811         /* acknowledge hold */
812         gsm_trace_header(p_m_mISDNport, this, MNCC_HOLD_CNF, DIRECTION_OUT);
813         end_trace();
814         resp = create_mncc(MNCC_HOLD_CNF, p_m_g_callref);
815         send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
816
817         /* disable audio */
818         if (p_m_g_tch_connected) { /* it should be true */
819                 gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_DROP, DIRECTION_OUT);
820                 end_trace();
821                 frame = create_mncc(MNCC_FRAME_DROP, p_m_g_callref);
822                 send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
823                 p_m_g_tch_connected = 0;
824         }
825 }
826
827
828 /* RETRIEVE INDICATION */
829 void Pgsm::retr_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
830 {
831         struct lcr_msg *message;
832         struct gsm_mncc *resp, *frame;
833
834         gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
835         end_trace();
836
837         /* notify the retrieve of call */
838         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
839         message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
840         message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
841         message_put(message);
842
843         /* acknowledge retr */
844         gsm_trace_header(p_m_mISDNport, this, MNCC_RETRIEVE_CNF, DIRECTION_OUT);
845         end_trace();
846         resp = create_mncc(MNCC_RETRIEVE_CNF, p_m_g_callref);
847         send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
848
849         /* enable audio */
850         if (!p_m_g_tch_connected) { /* it should be true */
851                 gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
852                 end_trace();
853                 frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
854                 send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
855                 p_m_g_tch_connected = 1;
856         }
857 }
858
859 /*
860  * BSC sends message to port
861  */
862 static int message_bsc(struct gsm_network *net, int msg_type, void *arg)
863 {
864         struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
865         unsigned int callref = mncc->callref;
866         class Port *port;
867         class Pgsm *pgsm = NULL;
868         char name[64];
869         struct mISDNport *mISDNport;
870
871         /* Special messages */
872         switch(msg_type) {
873         }
874
875         /* find callref */
876         callref = mncc->callref;
877         port = port_first;
878         while(port) {
879                 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_GSM) {
880                         pgsm = (class Pgsm *)port;
881                         if (pgsm->p_m_g_callref == callref) {
882                                 break;
883                         }
884                 }
885                 port = port->next;
886         }
887
888         if (msg_type == GSM_TCHF_FRAME) {
889                 if (port)
890                         pgsm->frame_receive((struct gsm_trau_frame *)arg);
891                 return 0;
892         }
893
894         if (!port) {
895                 if (msg_type != MNCC_SETUP_IND)
896                         return(0);
897                 /* find gsm port */
898                 mISDNport = mISDNport_first;
899                 while(mISDNport) {
900                         if (mISDNport->gsm)
901                                 break;
902                         mISDNport = mISDNport->next;
903                 }
904                 if (!mISDNport) {
905                         struct gsm_mncc *rej;
906
907                         rej = create_mncc(MNCC_REJ_REQ, callref);
908                         rej->fields |= MNCC_F_CAUSE;
909                         rej->cause.coding = 3;
910                         rej->cause.location = 1;
911                         rej->cause.value = 27;
912                         gsm_trace_header(NULL, NULL, MNCC_REJ_REQ, DIRECTION_OUT);
913                         add_trace("cause", "coding", "%d", rej->cause.coding);
914                         add_trace("cause", "location", "%d", rej->cause.location);
915                         add_trace("cause", "value", "%d", rej->cause.value);
916                         end_trace();
917                         send_and_free_mncc((struct gsm_network *)gsm->network, rej->msg_type, rej);
918                         return 0;
919                 }
920                 /* creating port object, transparent until setup with hdlc */
921                 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
922                 if (!(pgsm = new Pgsm(PORT_TYPE_GSM_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT)))
923
924                         FATAL("Cannot create Port instance.\n");
925         }
926
927         switch(msg_type) {
928                 case MNCC_SETUP_IND:
929                 pgsm->setup_ind(msg_type, callref, mncc);
930                 break;
931
932                 case MNCC_START_DTMF_IND:
933                 pgsm->start_dtmf_ind(msg_type, callref, mncc);
934                 break;
935
936                 case MNCC_STOP_DTMF_IND:
937                 pgsm->stop_dtmf_ind(msg_type, callref, mncc);
938                 break;
939
940                 case MNCC_CALL_CONF_IND:
941                 pgsm->call_conf_ind(msg_type, callref, mncc);
942                 break;
943
944                 case MNCC_ALERT_IND:
945                 pgsm->alert_ind(msg_type, callref, mncc);
946                 break;
947
948                 case MNCC_SETUP_CNF:
949                 pgsm->setup_cnf(msg_type, callref, mncc);
950                 break;
951
952                 case MNCC_SETUP_COMPL_IND:
953                 pgsm->setup_compl_ind(msg_type, callref, mncc);
954                 break;
955
956                 case MNCC_DISC_IND:
957                 pgsm->disc_ind(msg_type, callref, mncc);
958                 break;
959
960                 case MNCC_REL_IND:
961                 case MNCC_REL_CNF:
962                 case MNCC_REJ_IND:
963                 pgsm->rel_ind(msg_type, callref, mncc);
964                 break;
965
966                 case MNCC_NOTIFY_IND:
967                 pgsm->notify_ind(msg_type, callref, mncc);
968                 break;
969
970                 case MNCC_HOLD_IND:
971                 pgsm->hold_ind(msg_type, callref, mncc);
972                 break;
973
974                 case MNCC_RETRIEVE_IND:
975                 pgsm->retr_ind(msg_type, callref, mncc);
976                 break;
977
978                 default:
979                 PDEBUG(DEBUG_GSM, "Pgsm(%s) gsm port with (caller id %s) received unhandled nessage: 0x%x\n", pgsm->p_name, pgsm->p_callerinfo.id, msg_type);
980         }
981         return(0);
982 }
983
984 /* MESSAGE_SETUP */
985 void Pgsm::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
986 {
987         struct lcr_msg *message;
988         int ret;
989         struct epoint_list *epointlist;
990         struct gsm_mncc *mncc;
991         int channel;
992
993         /* copy setup infos to port */
994         memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
995         memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
996         memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
997         memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
998
999         /* no number */
1000         if (!p_dialinginfo.id[0]) {
1001                 gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
1002                 add_trace("failure", NULL, "No dialed subscriber given.");
1003                 end_trace();
1004                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1005                 message->param.disconnectinfo.cause = 28;
1006                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1007                 message_put(message);
1008                 new_state(PORT_STATE_RELEASE);
1009                 trigger_work(&p_m_g_delete);
1010                 return;
1011         }
1012         
1013         /* release if port is blocked */
1014         if (p_m_mISDNport->ifport->block) {
1015                 gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
1016                 add_trace("failure", NULL, "Port blocked.");
1017                 end_trace();
1018                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1019                 message->param.disconnectinfo.cause = 27; // temp. unavail.
1020                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1021                 message_put(message);
1022                 new_state(PORT_STATE_RELEASE);
1023                 trigger_work(&p_m_g_delete);
1024                 return;
1025         }
1026
1027         /* hunt channel */
1028         ret = channel = hunt_bchannel();
1029         if (ret < 0)
1030                 goto no_channel;
1031         /* open channel */
1032         ret = seize_bchannel(channel, 1);
1033         if (ret < 0) {
1034                 no_channel:
1035                 gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
1036                 add_trace("failure", NULL, "No internal audio channel available.");
1037                 end_trace();
1038                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1039                 message->param.disconnectinfo.cause = 34;
1040                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1041                 message_put(message);
1042                 new_state(PORT_STATE_RELEASE);
1043                 trigger_work(&p_m_g_delete);
1044                 return;
1045         }
1046         bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
1047         if (bchannel_open(p_m_b_index))
1048                 goto no_channel;
1049
1050 //              SCPY(&p_m_tones_dir, param->setup.ext.tones_dir);
1051         /* screen outgoing caller id */
1052         do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface);
1053
1054         /* attach only if not already */
1055         epointlist = p_epointlist;
1056         while(epointlist) {
1057                 if (epointlist->epoint_id == epoint_id)
1058                         break;
1059                 epointlist = epointlist->next;
1060         }
1061         if (!epointlist)
1062                 epointlist_new(epoint_id);
1063
1064         /* creating l3id */
1065         l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_L3ID_REQ, DIRECTION_OUT);
1066         p_m_g_callref = new_callref++;
1067         add_trace("callref", "new", "0x%x", p_m_g_callref);
1068         end_trace();
1069
1070         gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
1071         mncc = create_mncc(MNCC_SETUP_REQ, p_m_g_callref);
1072         /* caller information */
1073         mncc->fields |= MNCC_F_CALLING;
1074         mncc->calling.plan = 1;
1075         switch (p_callerinfo.ntype) {
1076                 case INFO_NTYPE_UNKNOWN:
1077                 mncc->calling.type = 0x0;
1078                 break;
1079                 case INFO_NTYPE_INTERNATIONAL:
1080                 mncc->calling.type = 0x1;
1081                 break;
1082                 case INFO_NTYPE_NATIONAL:
1083                 mncc->calling.type = 0x2;
1084                 break;
1085                 case INFO_NTYPE_SUBSCRIBER:
1086                 mncc->calling.type = 0x4;
1087                 break;
1088                 default: /* INFO_NTYPE_NOTPRESENT */
1089                 mncc->fields &= ~MNCC_F_CALLING;
1090                 break;
1091         }
1092         switch (p_callerinfo.screen) {
1093                 case INFO_SCREEN_USER:
1094                 mncc->calling.screen = 0;
1095                 break;
1096                 default: /* INFO_SCREEN_NETWORK */
1097                 mncc->calling.screen = 3;
1098                 break;
1099         }
1100         switch (p_callerinfo.present) {
1101                 case INFO_PRESENT_ALLOWED:
1102                 mncc->calling.present = 0;
1103                 break;
1104                 case INFO_PRESENT_RESTRICTED:
1105                 mncc->calling.present = 1;
1106                 break;
1107                 default: /* INFO_PRESENT_NOTAVAIL */
1108                 mncc->calling.present = 2;
1109                 break;
1110         }
1111         if (mncc->fields & MNCC_F_CALLING) {
1112                 SCPY(mncc->calling.number, p_callerinfo.id);
1113                 add_trace("calling", "type", "%d", mncc->calling.type);
1114                 add_trace("calling", "plan", "%d", mncc->calling.plan);
1115                 add_trace("calling", "present", "%d", mncc->calling.present);
1116                 add_trace("calling", "screen", "%d", mncc->calling.screen);
1117                 add_trace("calling", "number", "%s", mncc->calling.number);
1118         }
1119         /* dialing information */
1120         mncc->fields |= MNCC_F_CALLED;
1121         if (!strncmp(p_dialinginfo.id, "imsi-", 5)) {
1122                 SCPY(mncc->imsi, p_dialinginfo.id+5);
1123                 add_trace("dialing", "imsi", "%s", mncc->imsi);
1124         } else {
1125                 SCPY(mncc->called.number, p_dialinginfo.id);
1126                 add_trace("dialing", "number", "%s", mncc->called.number);
1127         }
1128         
1129         /* sending user-user */
1130
1131         /* redirecting number */
1132         mncc->fields |= MNCC_F_REDIRECTING;
1133         mncc->redirecting.plan = 1;
1134         switch (p_redirinfo.ntype) {
1135                 case INFO_NTYPE_UNKNOWN:
1136                 mncc->redirecting.type = 0x0;
1137                 break;
1138                 case INFO_NTYPE_INTERNATIONAL:
1139                 mncc->redirecting.type = 0x1;
1140                 break;
1141                 case INFO_NTYPE_NATIONAL:
1142                 mncc->redirecting.type = 0x2;
1143                 break;
1144                 case INFO_NTYPE_SUBSCRIBER:
1145                 mncc->redirecting.type = 0x4;
1146                 break;
1147                 default: /* INFO_NTYPE_NOTPRESENT */
1148                 mncc->fields &= ~MNCC_F_REDIRECTING;
1149                 break;
1150         }
1151         switch (p_redirinfo.screen) {
1152                 case INFO_SCREEN_USER:
1153                 mncc->redirecting.screen = 0;
1154                 break;
1155                 default: /* INFO_SCREE_NETWORK */
1156                 mncc->redirecting.screen = 3;
1157                 break;
1158         }
1159         switch (p_redirinfo.present) {
1160                 case INFO_PRESENT_ALLOWED:
1161                 mncc->redirecting.present = 0;
1162                 break;
1163                 case INFO_PRESENT_RESTRICTED:
1164                 mncc->redirecting.present = 1;
1165                 break;
1166                 default: /* INFO_PRESENT_NOTAVAIL */
1167                 mncc->redirecting.present = 2;
1168                 break;
1169         }
1170         /* sending redirecting number only in ntmode */
1171         if (mncc->fields & MNCC_F_REDIRECTING) {
1172                 SCPY(mncc->redirecting.number, p_redirinfo.id);
1173                 add_trace("redir", "type", "%d", mncc->redirecting.type);
1174                 add_trace("redir", "plan", "%d", mncc->redirecting.plan);
1175                 add_trace("redir", "present", "%d", mncc->redirecting.present);
1176                 add_trace("redir", "screen", "%d", mncc->redirecting.screen);
1177                 add_trace("redir", "number", "%s", mncc->redirecting.number);
1178         }
1179         /* bearer capability */
1180         //todo
1181
1182         end_trace();
1183         send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
1184
1185         new_state(PORT_STATE_OUT_SETUP);
1186
1187         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
1188         message_put(message);
1189
1190         new_state(PORT_STATE_OUT_PROCEEDING);
1191 }
1192
1193 /* MESSAGE_NOTIFY */
1194 void Pgsm::message_notify(unsigned int epoint_id, int message_id, union parameter *param)
1195 {
1196         struct gsm_mncc *mncc;
1197         int notify;
1198
1199 //      printf("if = %d\n", param->notifyinfo.notify);
1200         if (param->notifyinfo.notify>INFO_NOTIFY_NONE) {
1201                 notify = param->notifyinfo.notify & 0x7f;
1202                 if (p_state!=PORT_STATE_CONNECT /*&& p_state!=PORT_STATE_IN_PROCEEDING*/ && p_state!=PORT_STATE_IN_ALERTING) {
1203                         /* queue notification */
1204                         if (p_m_g_notify_pending)
1205                                 message_free(p_m_g_notify_pending);
1206                         p_m_g_notify_pending = message_create(ACTIVE_EPOINT(p_epointlist), p_serial, EPOINT_TO_PORT, message_id);
1207                         memcpy(&p_m_g_notify_pending->param, param, sizeof(union parameter));
1208                 } else {
1209                         /* sending notification */
1210                         gsm_trace_header(p_m_mISDNport, this, MNCC_NOTIFY_REQ, DIRECTION_OUT);
1211                         add_trace("notify", NULL, "%d", notify);
1212                         end_trace();
1213                         mncc = create_mncc(MNCC_NOTIFY_REQ, p_m_g_callref);
1214                         mncc->notify = notify;
1215                         send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
1216                 }
1217         }
1218 }
1219
1220 /* MESSAGE_ALERTING */
1221 void Pgsm::message_alerting(unsigned int epoint_id, int message_id, union parameter *param)
1222 {
1223         struct gsm_mncc *mncc;
1224
1225         /* send alert */
1226         gsm_trace_header(p_m_mISDNport, this, MNCC_ALERT_REQ, DIRECTION_OUT);
1227         mncc = create_mncc(MNCC_ALERT_REQ, p_m_g_callref);
1228         if (p_m_mISDNport->tones) {
1229                 mncc->fields |= MNCC_F_PROGRESS;
1230                 mncc->progress.coding = 3; /* GSM */
1231                 mncc->progress.location = 1;
1232                 mncc->progress.descr = 8;
1233                 add_trace("progress", "coding", "%d", mncc->progress.coding);
1234                 add_trace("progress", "location", "%d", mncc->progress.location);
1235                 add_trace("progress", "descr", "%d", mncc->progress.descr);
1236         }
1237         end_trace();
1238         send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
1239
1240         new_state(PORT_STATE_IN_ALERTING);
1241
1242         if (p_m_mISDNport->tones && !p_m_g_tch_connected) { /* only if ... */
1243                 gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
1244                 end_trace();
1245                 mncc = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
1246                 send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
1247                 p_m_g_tch_connected = 1;
1248         }
1249 }
1250
1251 /* MESSAGE_CONNECT */
1252 void Pgsm::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
1253 {
1254         struct gsm_mncc *mncc;
1255
1256         /* copy connected information */
1257         memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
1258         /* screen outgoing caller id */
1259         do_screen(1, p_connectinfo.id, sizeof(p_connectinfo.id), &p_connectinfo.ntype, &p_connectinfo.present, p_m_mISDNport->ifport->interface);
1260
1261         /* send connect */
1262         mncc = create_mncc(MNCC_SETUP_RSP, p_m_g_callref);
1263         gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_RSP, DIRECTION_OUT);
1264         /* caller information */
1265         mncc->fields |= MNCC_F_CONNECTED;
1266         mncc->connected.plan = 1;
1267         switch (p_callerinfo.ntype) {
1268                 case INFO_NTYPE_UNKNOWN:
1269                 mncc->connected.type = 0x0;
1270                 break;
1271                 case INFO_NTYPE_INTERNATIONAL:
1272                 mncc->connected.type = 0x1;
1273                 break;
1274                 case INFO_NTYPE_NATIONAL:
1275                 mncc->connected.type = 0x2;
1276                 break;
1277                 case INFO_NTYPE_SUBSCRIBER:
1278                 mncc->connected.type = 0x4;
1279                 break;
1280                 default: /* INFO_NTYPE_NOTPRESENT */
1281                 mncc->fields &= ~MNCC_F_CONNECTED;
1282                 break;
1283         }
1284         switch (p_callerinfo.screen) {
1285                 case INFO_SCREEN_USER:
1286                 mncc->connected.screen = 0;
1287                 break;
1288                 default: /* INFO_SCREEN_NETWORK */
1289                 mncc->connected.screen = 3;
1290                 break;
1291         }
1292         switch (p_callerinfo.present) {
1293                 case INFO_PRESENT_ALLOWED:
1294                 mncc->connected.present = 0;
1295                 break;
1296                 case INFO_PRESENT_RESTRICTED:
1297                 mncc->connected.present = 1;
1298                 break;
1299                 default: /* INFO_PRESENT_NOTAVAIL */
1300                 mncc->connected.present = 2;
1301                 break;
1302         }
1303         if (mncc->fields & MNCC_F_CONNECTED) {
1304                 SCPY(mncc->connected.number, p_connectinfo.id);
1305                 add_trace("connected", "type", "%d", mncc->connected.type);
1306                 add_trace("connected", "plan", "%d", mncc->connected.plan);
1307                 add_trace("connected", "present", "%d", mncc->connected.present);
1308                 add_trace("connected", "screen", "%d", mncc->connected.screen);
1309                 add_trace("connected", "number", "%s", mncc->connected.number);
1310         }
1311         end_trace();
1312         send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
1313
1314         new_state(PORT_STATE_CONNECT_WAITING);
1315 }
1316
1317 /* MESSAGE_DISCONNECT */
1318 void Pgsm::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
1319 {
1320         struct gsm_mncc *mncc;
1321
1322         /* send disconnect */
1323         mncc = create_mncc(MNCC_DISC_REQ, p_m_g_callref);
1324         gsm_trace_header(p_m_mISDNport, this, MNCC_DISC_REQ, DIRECTION_OUT);
1325         if (p_m_mISDNport->tones) {
1326                 mncc->fields |= MNCC_F_PROGRESS;
1327                 mncc->progress.coding = 3; /* GSM */
1328                 mncc->progress.location = 1;
1329                 mncc->progress.descr = 8;
1330                 add_trace("progress", "coding", "%d", mncc->progress.coding);
1331                 add_trace("progress", "location", "%d", mncc->progress.location);
1332                 add_trace("progress", "descr", "%d", mncc->progress.descr);
1333         }
1334         mncc->fields |= MNCC_F_CAUSE;
1335         mncc->cause.coding = 3;
1336         mncc->cause.location = param->disconnectinfo.location;
1337         mncc->cause.value = param->disconnectinfo.cause;
1338         add_trace("cause", "coding", "%d", mncc->cause.coding);
1339         add_trace("cause", "location", "%d", mncc->cause.location);
1340         add_trace("cause", "value", "%d", mncc->cause.value);
1341         end_trace();
1342         send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
1343
1344         new_state(PORT_STATE_OUT_DISCONNECT);
1345
1346         if (p_m_mISDNport->tones && !p_m_g_tch_connected) { /* only if ... */
1347                 gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
1348                 end_trace();
1349                 mncc = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
1350                 send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
1351                 p_m_g_tch_connected = 1;
1352         }
1353 }
1354
1355
1356 /* MESSAGE_RELEASE */
1357 void Pgsm::message_release(unsigned int epoint_id, int message_id, union parameter *param)
1358 {
1359         struct gsm_mncc *mncc;
1360
1361         /* send release */
1362         mncc = create_mncc(MNCC_REL_REQ, p_m_g_callref);
1363         gsm_trace_header(p_m_mISDNport, this, MNCC_REL_REQ, DIRECTION_OUT);
1364         mncc->fields |= MNCC_F_CAUSE;
1365         mncc->cause.coding = 3;
1366         mncc->cause.location = param->disconnectinfo.location;
1367         mncc->cause.value = param->disconnectinfo.cause;
1368         add_trace("cause", "coding", "%d", mncc->cause.coding);
1369         add_trace("cause", "location", "%d", mncc->cause.location);
1370         add_trace("cause", "value", "%d", mncc->cause.value);
1371         end_trace();
1372         send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
1373
1374         new_state(PORT_STATE_RELEASE);
1375         trigger_work(&p_m_g_delete);
1376         return;
1377 }
1378
1379
1380 /*
1381  * endpoint sends messages to the port
1382  */
1383 int Pgsm::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1384 {
1385         if (PmISDN::message_epoint(epoint_id, message_id, param))
1386                 return(1);
1387
1388         switch(message_id) {
1389                 case MESSAGE_SETUP: /* dial-out command received from epoint */
1390                 if (p_state!=PORT_STATE_IDLE)
1391                         break;
1392                 message_setup(epoint_id, message_id, param);
1393                 break;
1394
1395                 case MESSAGE_NOTIFY: /* display and notifications */
1396                 message_notify(epoint_id, message_id, param);
1397                 break;
1398
1399 //              case MESSAGE_FACILITY: /* facility message */
1400 //              message_facility(epoint_id, message_id, param);
1401 //              break;
1402
1403                 case MESSAGE_PROCEEDING: /* message not handles */
1404                 break;
1405
1406                 case MESSAGE_ALERTING: /* call of endpoint is ringing */
1407                 if (p_state!=PORT_STATE_IN_PROCEEDING)
1408                         break;
1409                 message_alerting(epoint_id, message_id, param);
1410                 if (p_m_g_notify_pending) {
1411                         /* send pending notify message during connect */
1412                         message_notify(ACTIVE_EPOINT(p_epointlist), p_m_g_notify_pending->type, &p_m_g_notify_pending->param);
1413                         message_free(p_m_g_notify_pending);
1414                         p_m_g_notify_pending = NULL;
1415                 }
1416                 break;
1417
1418                 case MESSAGE_CONNECT: /* call of endpoint is connected */
1419                 if (p_state!=PORT_STATE_IN_PROCEEDING
1420                  && p_state!=PORT_STATE_IN_ALERTING)
1421                         break;
1422                 message_connect(epoint_id, message_id, param);
1423                 if (p_m_g_notify_pending) {
1424                         /* send pending notify message during connect */
1425                         message_notify(ACTIVE_EPOINT(p_epointlist), p_m_g_notify_pending->type, &p_m_g_notify_pending->param);
1426                         message_free(p_m_g_notify_pending);
1427                         p_m_g_notify_pending = NULL;
1428                 }
1429                 break;
1430
1431                 case MESSAGE_DISCONNECT: /* call has been disconnected */
1432                 if (p_state!=PORT_STATE_IN_PROCEEDING
1433                  && p_state!=PORT_STATE_IN_ALERTING
1434                  && p_state!=PORT_STATE_OUT_SETUP
1435                  && p_state!=PORT_STATE_OUT_OVERLAP
1436                  && p_state!=PORT_STATE_OUT_PROCEEDING
1437                  && p_state!=PORT_STATE_OUT_ALERTING
1438                  && p_state!=PORT_STATE_CONNECT
1439                  && p_state!=PORT_STATE_CONNECT_WAITING)
1440                         break;
1441                 message_disconnect(epoint_id, message_id, param);
1442                 break;
1443
1444                 case MESSAGE_RELEASE: /* release isdn port */
1445                 if (p_state==PORT_STATE_RELEASE)
1446                         break;
1447                 message_release(epoint_id, message_id, param);
1448                 break;
1449
1450                 default:
1451                 PDEBUG(DEBUG_GSM, "Pgsm(%s) gsm port with (caller id %s) received unhandled nessage: %d\n", p_name, p_callerinfo.id, message_id);
1452         }
1453
1454         return(1);
1455 }
1456
1457
1458 /* deletes only if l3id is release, otherwhise it will be triggered then */
1459 static int delete_event(struct lcr_work *work, void *instance, int index)
1460 {
1461         class Pgsm *gsmport = (class Pgsm *)instance;
1462
1463         delete gsmport;
1464
1465         return 0;
1466 }
1467
1468 /*
1469  * handler of bchannel events
1470  */
1471 static int b_handler(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1472 {
1473         class Pgsm *gsmport = (class Pgsm *)instance;
1474         int ret;
1475         unsigned char buffer[2048+MISDN_HEADER_LEN];
1476         struct mISDNhead *hh = (struct mISDNhead *)buffer;
1477
1478         /* handle message from bchannel */
1479         if (gsmport->p_m_g_gsm_b_sock > -1) {
1480                 ret = recv(gsmport->p_m_g_gsm_b_sock, buffer, sizeof(buffer), 0);
1481                 if (ret >= (int)MISDN_HEADER_LEN) {
1482                         switch(hh->prim) {
1483                                 /* we don't care about confirms, we use rx data to sync tx */
1484                                 case PH_DATA_CNF:
1485                                 break;
1486                                 /* we receive audio data, we respond to it AND we send tones */
1487                                 case PH_DATA_IND:
1488                                 gsmport->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1489                                 break;
1490                                 case PH_ACTIVATE_IND:
1491                                 gsmport->p_m_g_gsm_b_active = 1;
1492                                 break;
1493                                 case PH_DEACTIVATE_IND:
1494                                 gsmport->p_m_g_gsm_b_active = 0;
1495                                 break;
1496                         }
1497                 } else {
1498                         if (ret < 0 && errno != EWOULDBLOCK)
1499                                 PERROR("Read from GSM port, index %d failed with return code %d\n", ret);
1500                 }
1501         }
1502
1503         return 0;
1504 }
1505
1506 static void gsm_sock_close(void)
1507 {
1508         if (gsm->gsm_sock > -1)
1509                 close(gsm->gsm_sock);
1510         gsm->gsm_sock = -1;
1511 }
1512
1513 static int gsm_sock_open(char *portname)
1514 {
1515         int ret;
1516         int cnt;
1517         unsigned long on = 1;
1518         struct sockaddr_mISDN addr;
1519         struct mISDN_devinfo devinfo;
1520         int pri, bri;
1521
1522         /* check port counts */
1523         ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
1524         if (ret < 0) {
1525                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
1526                 return(ret);
1527         }
1528
1529         if (cnt <= 0) {
1530                 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
1531                 return -EIO;
1532         }
1533         gsm->gsm_port = mISDN_getportbyname(mISDNsocket, cnt, portname);
1534         if (gsm->gsm_port < 0) {
1535                 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", portname);
1536                 return gsm->gsm_port;
1537         }
1538         /* get protocol */
1539         bri = pri = 0;
1540         devinfo.id = gsm->gsm_port;
1541         ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
1542         if (ret < 0) {
1543                 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", gsm->gsm_port, ret);
1544                 return ret;
1545         }
1546         if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
1547                 bri = 1;
1548         }
1549         if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
1550                 pri = 1;
1551         }
1552         if (!pri && !pri) {
1553                 PERROR_RUNTIME("GSM port %d does not support TE PRI or TE BRI.\n", gsm->gsm_port);
1554         }
1555         /* open socket */
1556         if ((gsm->gsm_sock = socket(PF_ISDN, SOCK_DGRAM, (pri)?ISDN_P_TE_E1:ISDN_P_TE_S0)) < 0) {
1557                 PERROR_RUNTIME("GSM port %d failed to open socket.\n", gsm->gsm_port);
1558                 gsm_sock_close();
1559                 return gsm->gsm_sock;
1560         }
1561         /* set nonblocking io */
1562         if ((ret = ioctl(gsm->gsm_sock, FIONBIO, &on)) < 0) {
1563                 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", gsm->gsm_port);
1564                 gsm_sock_close();
1565                 return ret;
1566         }
1567         /* bind socket to dchannel */
1568         memset(&addr, 0, sizeof(addr));
1569         addr.family = AF_ISDN;
1570         addr.dev = gsm->gsm_port;
1571         addr.channel = 0;
1572         if ((ret = bind(gsm->gsm_sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) {
1573                 PERROR_RUNTIME("GSM port %d failed to bind socket. (name = %s errno=%d)\n", gsm->gsm_port, portname, errno);
1574                 gsm_sock_close();
1575                 return (ret);
1576         }
1577
1578         return 0;
1579 }
1580
1581
1582 int gsm_exit(int rc)
1583 {
1584         /* free gsm instance */
1585         if (gsm) {
1586                 if (gsm->gsm_sock > -1)
1587                         gsm_sock_close();
1588                 /* shutdown network */
1589                 if (gsm->network)
1590                         bsc_shutdown_net((struct gsm_network *)gsm->network);
1591                 /* free network */
1592 //              if (gsm->network) {
1593 //                      free((struct gsm_network *)gsm->network); /* TBD */
1594 //              }
1595                 free(gsm);
1596                 gsm = NULL;
1597         }
1598
1599         return(rc);
1600 }
1601
1602 int gsm_init(void)
1603 {
1604         char hlr[128], cfg[128], filename[128];
1605         mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1606         int pcapfd, rc;
1607         char conf_error[128] = "";
1608
1609
1610         debug_init();
1611         tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1612         talloc_ctx_init();
1613         on_dso_load_token();
1614         on_dso_load_rrlp();
1615         on_dso_load_ho_dec();
1616         stderr_target = debug_target_create_stderr();
1617         debug_add_target(stderr_target);
1618
1619         bts_model_unknown_init();
1620         bts_model_bs11_init();
1621         bts_model_nanobts_init();
1622
1623         /* enable filters */
1624         debug_set_all_filter(stderr_target, 1);
1625
1626         /* seed the PRNG */
1627         srand(time(NULL));
1628
1629         /* create gsm instance */
1630         gsm = (struct lcr_gsm *)MALLOC(sizeof(struct lcr_gsm));
1631         gsm->gsm_sock = -1;
1632
1633         /* parse options */
1634         if (!gsm_conf(&gsm->conf, conf_error)) {
1635                 PERROR("%s", conf_error);
1636                 return gsm_exit(-EINVAL);
1637         }
1638
1639         /* set debug */
1640         if (gsm->conf.debug[0])
1641                 debug_parse_category_mask(stderr_target, gsm->conf.debug);
1642
1643         /* open pcap file */
1644         if (gsm->conf.pcapfile[0]) {
1645                 if (gsm->conf.pcapfile[0] == '/')
1646                         SCPY(filename, gsm->conf.pcapfile);
1647                 else
1648                         SPRINT(filename, "%s/%s", CONFIG_DATA, gsm->conf.pcapfile);
1649                 pcapfd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, mode);
1650                 if (pcapfd < 0) {
1651                         PERROR("Failed to open file for pcap\n");
1652                         return gsm_exit(-1);
1653                 }
1654                 e1_set_pcap_fd(pcapfd);
1655         }
1656
1657         /* use RTP proxy for audio streaming */
1658         ipacc_rtp_direct = 0;
1659
1660         /* init database */
1661         if (gsm->conf.hlr[0] == '/')
1662                 SCPY(hlr, gsm->conf.hlr);
1663         else
1664                 SPRINT(hlr, "%s/%s", CONFIG_DATA, gsm->conf.hlr);
1665         if (db_init(hlr)) {
1666                 PERROR("GSM DB: Failed to init database '%s'. Please check the option settings.\n", hlr);
1667                 return gsm_exit(-1);
1668         }
1669         printf("DB: Database initialized.\n");
1670         if (db_prepare()) {
1671                 PERROR("GSM DB: Failed to prepare database.\n");
1672                 return gsm_exit(-1);
1673         }
1674         printf("DB: Database prepared.\n");
1675
1676         /* setup the timer */
1677         db_sync_timer.cb = db_sync_timer_cb;
1678         db_sync_timer.data = NULL;
1679         bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
1680
1681         /* bootstrap network */
1682         if (gsm->conf.openbsc_cfg[0] == '/')
1683                 SCPY(cfg, gsm->conf.openbsc_cfg);
1684         else
1685                 SPRINT(cfg, "%s/%s", CONFIG_DATA, gsm->conf.openbsc_cfg);
1686         rc = bsc_bootstrap_network(&message_bsc, cfg);
1687         if (rc < 0) {
1688                 PERROR("Failed to bootstrap GSM network.\n");
1689                 return gsm_exit(-1);
1690         }
1691         gsm->network = bsc_gsmnet;
1692
1693         /* open gsm loop interface */
1694         if (gsm_sock_open(gsm->conf.interface_bsc)) {
1695                 return gsm_exit(-1);
1696         }
1697
1698         return 0;
1699 }
1700
1701 /*
1702  * handles bsc select function within LCR's main loop
1703  */
1704 int handle_gsm(void)
1705 {
1706         int ret1, ret2;
1707
1708         ret1 = bsc_upqueue((struct gsm_network *)gsm->network);
1709         debug_reset_context();
1710         ret2 = bsc_select_main(1); /* polling */
1711         if (ret1 || ret2)
1712                 return 1;
1713         return 0;
1714 }
1715