1 /* Synchronous part of GSM Layer 1: API to Layer2+ */
3 /* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <comm/msgb.h>
27 #include <comm/sercomm.h>
29 #include <layer1/sync.h>
30 #include <layer1/async.h>
31 #include <layer1/mframe_sched.h>
33 #include <l1a_l23_interface.h>
35 /* the size we will allocate struct msgb* for HDLC */
36 #define L3_MSG_SIZE (sizeof(struct l1ctl_data_ind) + 4)
39 void l1_queue_for_l2(struct msgb *msg)
41 /* forward via serial for now */
42 sercomm_sendmsg(SC_DLCI_L1A_L23, msg);
45 struct msgb *l1_create_l2_msg(int msg_type, uint32_t fn, uint16_t snr)
47 struct l1ctl_info_dl *dl;
50 msg = msgb_alloc_headroom(L3_MSG_SIZE, L3_MSG_HEAD, "l1_burst");
53 puts("OOPS. Out of buffers...\n");
59 dl = (struct l1ctl_info_dl *) msgb_put(msg, sizeof(*dl));
60 dl->msg_type = msg_type;
61 /* FIXME: we may want to compute T1/T2/T3 in L23 */
62 gsm_fn2gsmtime(&dl->time, fn);
68 /* callbakc from SERCOMM when L2 sends a message to L1 */
69 static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg)
71 struct l1ctl_info_ul *ul = msg->data;
72 struct l1ctl_sync_new_ccch_req *sync_req;
73 struct l1ctl_rach_req *rach_req;
74 struct l1ctl_dedic_mode_est_req *est_req;
75 struct l1ctl_data_ind *data_ind;
76 struct llist_head *tx_queue;
78 if (sizeof(*ul) > msg->len) {
79 printf("l1a_l23_cb: Short message. %u\n", msg->len);
83 switch (ul->msg_type) {
84 case L1CTL_NEW_CCCH_REQ:
85 if (sizeof(*ul) + sizeof(*sync_req) > msg->len) {
86 printf("Short sync msg. %u\n", msg->len);
90 sync_req = (struct l1ctl_sync_new_ccch_req *) (&msg->data[0] + sizeof(*ul));
91 printf("Asked to tune to frequency: %u\n", sync_req->band_arfcn);
93 /* reset scheduler and hardware */
97 /* tune to specified frequency */
98 trf6151_rx_window(0, sync_req->band_arfcn, 40, 0);
101 puts("Starting FCCH Recognition\n");
104 case L1CTL_DM_EST_REQ:
105 est_req = (struct l1ctl_dm_est_req *) ul->payload;
107 /* FIXME: Timeslot */
108 /* figure out which MF tasks to enable, depending on channel number */
109 l1s.mf_tasks = (1 << MF_TASK_SDCCH4_0);
112 puts("CCCH_RACH_REQ\n");
113 rach_req = (struct l1ctl_rach_req *) ul->payload;
114 l1a_rach_req(27, rach_req->ra);
117 puts("DEDIC_MODE_DATA_REQ\n");
118 data_ind = (struct l1ctl_data_ind *) ul->payload;
119 if (ul->link_id & 0x40)
120 tx_queue = &l1s.tx_queue[L1S_CHAN_SACCH];
122 tx_queue = &l1s.tx_queue[L1S_CHAN_MAIN];
123 msg->l3h = data_ind->data;
124 l1a_txq_msgb_enq(tx_queue, msg);
132 void l1a_l23api_init(void)
134 sercomm_register_rx_cb(SC_DLCI_L1A_L23, l1a_l23_rx_cb);