blob: 8db402b33a0ab71312a4038cf791c36c0cbea4e7 [file] [log] [blame]
Daniel Willmann8b3390e2008-12-28 00:31:09 +00001/* Point-to-Point (PP) Short Message Service (SMS)
2 * Support on Mobile Radio Interface
3 * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */
4
5/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
Harald Welte7e310b12009-03-30 20:56:32 +00006 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
Daniel Willmann8b3390e2008-12-28 00:31:09 +00007 *
8 * All Rights Reserved
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 *
24 */
25
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <errno.h>
31#include <netinet/in.h>
32
33#include <openbsc/msgb.h>
Harald Welte7e310b12009-03-30 20:56:32 +000034#include <openbsc/tlv.h>
Daniel Willmann8b3390e2008-12-28 00:31:09 +000035#include <openbsc/debug.h>
Daniel Willmann471712b2008-12-29 01:54:02 +000036#include <openbsc/gsm_data.h>
37#include <openbsc/gsm_subscriber.h>
Daniel Willmann8b3390e2008-12-28 00:31:09 +000038#include <openbsc/gsm_04_11.h>
39#include <openbsc/gsm_04_08.h>
Holger Freyther76c95692009-02-17 20:31:30 +000040#include <openbsc/gsm_utils.h>
Daniel Willmann8b3390e2008-12-28 00:31:09 +000041#include <openbsc/abis_rsl.h>
Holger Freyther9b177762009-02-16 19:07:18 +000042#include <openbsc/signal.h>
Harald Welte7e310b12009-03-30 20:56:32 +000043#include <openbsc/db.h>
Harald Welte2cf161b2009-06-20 22:36:41 +020044#include <openbsc/talloc.h>
Daniel Willmann8b3390e2008-12-28 00:31:09 +000045
Daniel Willmann471712b2008-12-29 01:54:02 +000046#define GSM411_ALLOC_SIZE 1024
47#define GSM411_ALLOC_HEADROOM 128
48
Harald Welte2cf161b2009-06-20 22:36:41 +020049static void *tall_sms_ctx;
50static void *tall_gsms_ctx;
51
Holger Freythera553d092009-01-04 20:16:25 +000052struct msgb *gsm411_msgb_alloc(void)
Daniel Willmann471712b2008-12-29 01:54:02 +000053{
Harald Welte966636f2009-06-26 19:39:35 +020054 return msgb_alloc_headroom(GSM411_ALLOC_SIZE, GSM411_ALLOC_HEADROOM,
55 "GSM 04.11");
Daniel Willmann471712b2008-12-29 01:54:02 +000056}
57
Holger Freythera553d092009-01-04 20:16:25 +000058int gsm0411_sendmsg(struct msgb *msg)
Daniel Willmann471712b2008-12-29 01:54:02 +000059{
60 if (msg->lchan)
61 msg->trx = msg->lchan->ts->trx;
62
63 msg->l3h = msg->data;
64
65 return rsl_data_request(msg, 0);
66}
67
Daniel Willmanne0fbec82008-12-29 00:44:41 +000068
Holger Freytherca362a62009-01-04 21:05:01 +000069#if 0
Daniel Willmann6fe997e2008-12-29 04:20:41 +000070static u_int8_t gsm0411_tpdu_from_sms(u_int8_t *tpdu, struct sms_deliver *sms)
71{
Daniel Willmann6fe997e2008-12-29 04:20:41 +000072}
Holger Freytherca362a62009-01-04 21:05:01 +000073#endif
Daniel Willmann6fe997e2008-12-29 04:20:41 +000074
Harald Welte7e310b12009-03-30 20:56:32 +000075static unsigned long gsm340_validity_period(struct sms_submit *sms)
76{
77 u_int8_t vp;
78 unsigned long minutes;
79
80 switch (sms->vpf) {
81 case GSM340_TP_VPF_RELATIVE:
82 /* Chapter 9.2.3.12.1 */
83 vp = *(sms->vp);
84 if (vp <= 143)
85 minutes = vp + 1 * 5;
86 else if (vp <= 167)
87 minutes = 12*60 + (vp-143) * 30;
88 else if (vp <= 196)
89 minutes = vp-166 * 60 * 24;
90 else
91 minutes = vp-192 * 60 * 24 * 7;
92 break;
93 case GSM340_TP_VPF_ABSOLUTE:
94 /* Chapter 9.2.3.12.2 */
95 /* FIXME: like service center time stamp */
96 DEBUGP(DSMS, "VPI absolute not implemented yet\n");
97 break;
98 case GSM340_TP_VPF_ENHANCED:
99 /* Chapter 9.2.3.12.3 */
100 /* FIXME: implementation */
101 DEBUGP(DSMS, "VPI enhanced not implemented yet\n");
102 break;
103 }
104 return minutes;
105}
106
107/* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
108enum sms_alphabet gsm338_get_sms_alphabet(u_int8_t dcs)
109{
110 u_int8_t cgbits = dcs >> 4;
111 enum sms_alphabet alpha = DCS_NONE;
112
113 if ((cgbits & 0xc) == 0) {
114 if (cgbits & 2)
115 DEBUGP(DSMS, "Compressed SMS not supported yet\n");
116
117 switch (dcs & 3) {
118 case 0:
119 alpha = DCS_7BIT_DEFAULT;
120 break;
121 case 1:
122 alpha = DCS_8BIT_DATA;
123 break;
124 case 2:
125 alpha = DCS_UCS2;
126 break;
127 }
128 } else if (cgbits == 0xc || cgbits == 0xd)
129 alpha = DCS_7BIT_DEFAULT;
130 else if (cgbits == 0xe)
131 alpha = DCS_UCS2;
132 else if (cgbits == 0xf) {
133 if (dcs & 4)
134 alpha = DCS_8BIT_DATA;
135 else
136 alpha = DCS_7BIT_DEFAULT;
137 }
138
139 return alpha;
140}
141
142static int gsm340_rx_sms_submit(struct msgb *msg, struct sms_submit *sms,
143 struct gsm_sms *gsms)
144{
145 if (db_sms_store(gsms) != 0) {
146 DEBUGP(DSMS, "Failed to store SMS in Database\n");
Harald Welte2cf161b2009-06-20 22:36:41 +0200147 talloc_free(sms);
148 talloc_free(gsms);
Harald Welte7e310b12009-03-30 20:56:32 +0000149 return -EIO;
150 }
151 return 0;
152}
153
154/* process an incoming TPDU (called from RP-DATA) */
155static int gsm340_rx_tpdu(struct msgb *msg)
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000156{
Harald Welte761e9442009-07-23 19:21:02 +0200157 struct gsm_bts *bts = msg->lchan->ts->trx->bts;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000158 u_int8_t *smsp = msgb_sms(msg);
159 struct sms_submit *sms;
Harald Welte7e310b12009-03-30 20:56:32 +0000160 struct gsm_sms *gsms;
161 u_int8_t da_len_bytes;
162 u_int8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
163 int rc = 0;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000164
Harald Welte2cf161b2009-06-20 22:36:41 +0200165 if (!tall_sms_ctx)
166 tall_sms_ctx = talloc_named_const(tall_bsc_ctx, 1,
167 "sms_submit");
168
169 sms = talloc(tall_sms_ctx, struct sms_submit);
Harald Welte7e310b12009-03-30 20:56:32 +0000170 if (!sms)
171 return -ENOMEM;
172 memset(sms, 0, sizeof(*sms));
173
Harald Welte2cf161b2009-06-20 22:36:41 +0200174 if (!tall_gsms_ctx)
175 tall_gsms_ctx = talloc_named_const(tall_bsc_ctx, 1,
176 "sms");
177
178 gsms = talloc(tall_gsms_ctx, struct gsm_sms);
Harald Welte7e310b12009-03-30 20:56:32 +0000179 if (!gsms) {
Harald Welte2cf161b2009-06-20 22:36:41 +0200180 talloc_free(sms);
Harald Welte7e310b12009-03-30 20:56:32 +0000181 return -ENOMEM;
182 }
183 memset(gsms, 0, sizeof(*gsms));
184
185 /* invert those fields where 0 means active/present */
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000186 sms->mti = *smsp & 0x03;
187 sms->mms = !!(*smsp & 0x04);
188 sms->vpf = (*smsp & 0x18) >> 3;
189 sms->sri = !!(*smsp & 0x20);
190 sms->udhi= !!(*smsp & 0x40);
191 sms->rp = !!(*smsp & 0x80);
192
193 smsp++;
194 sms->msg_ref = *smsp++;
195
Harald Welte7e310b12009-03-30 20:56:32 +0000196 /* length in bytes of the destination address */
197 da_len_bytes = 2 + *smsp/2 + *smsp%2;
198 if (da_len_bytes > 12) {
199 DEBUGP(DSMS, "Destination Address > 12 bytes ?!?\n");
200 rc = -EIO;
201 goto out;
202 }
Harald Welte3cfdb222009-06-12 02:42:11 +0800203 memset(address_lv, 0, sizeof(address_lv));
Harald Welte7e310b12009-03-30 20:56:32 +0000204 memcpy(address_lv, smsp, da_len_bytes);
205 /* mangle first byte to reflect length in bytes, not digits */
Harald Welte3cfdb222009-06-12 02:42:11 +0800206 address_lv[0] = da_len_bytes - 1;
Harald Welte7e310b12009-03-30 20:56:32 +0000207 /* convert to real number */
Harald Welte3cfdb222009-06-12 02:42:11 +0800208 decode_bcd_number(sms->dest_addr, sizeof(sms->dest_addr), address_lv, 1);
Harald Welte7e310b12009-03-30 20:56:32 +0000209
210 smsp += da_len_bytes;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000211
212 sms->pid = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000213
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000214 sms->dcs = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000215 sms->alphabet = gsm338_get_sms_alphabet(sms->dcs);
216
217 switch (sms->vpf) {
218 case GSM340_TP_VPF_RELATIVE:
219 sms->vp = smsp++;
220 break;
221 case GSM340_TP_VPF_ABSOLUTE:
222 case GSM340_TP_VPF_ENHANCED:
223 sms->vp = smsp;
224 smsp += 7;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000225 break;
226 default:
227 DEBUGP(DSMS, "SMS Validity period not implemented: 0x%02x\n",
228 sms->vpf);
229 }
230 sms->ud_len = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000231 if (sms->ud_len)
232 sms->user_data = smsp;
233 else
234 sms->user_data = NULL;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000235
Harald Welte7e310b12009-03-30 20:56:32 +0000236 if (sms->ud_len) {
237 switch (sms->alphabet) {
238 case DCS_7BIT_DEFAULT:
239 gsm_7bit_decode(sms->decoded, smsp, sms->ud_len);
240 break;
241 case DCS_8BIT_DATA:
242 case DCS_UCS2:
243 case DCS_NONE:
244 memcpy(sms->decoded, sms->user_data, sms->ud_len);
245 break;
246 }
247 }
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000248
Harald Welte7e310b12009-03-30 20:56:32 +0000249 DEBUGP(DSMS, "SMS:\nMTI: 0x%02x, VPF: 0x%02x, MR: 0x%02x "
250 "PID: 0x%02x, DCS: 0x%02x, DA: %s, UserDataLength: 0x%02x "
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000251 "UserData: \"%s\"\n", sms->mti, sms->vpf, sms->msg_ref,
Harald Welte7e310b12009-03-30 20:56:32 +0000252 sms->pid, sms->dcs, sms->dest_addr, sms->ud_len,
253 sms->alphabet == DCS_7BIT_DEFAULT ? sms->decoded : hexdump(sms->user_data, sms->ud_len));
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000254
Harald Welte595ad7b2009-02-16 22:05:44 +0000255 dispatch_signal(SS_SMS, 0, sms);
Holger Freyther9b177762009-02-16 19:07:18 +0000256
Harald Welte7e310b12009-03-30 20:56:32 +0000257 gsms->sender = msg->lchan->subscr;
258 /* FIXME: sender refcount */
259
260 /* determine gsms->receiver based on dialled number */
Harald Welte761e9442009-07-23 19:21:02 +0200261 gsms->receiver = subscr_get_by_extension(bts->network, sms->dest_addr);
Harald Welte7e310b12009-03-30 20:56:32 +0000262 if (!gsms->receiver) {
263 rc = 1; /* cause 1: unknown subscriber */
264 goto out;
265 }
266
267 if (sms->user_data)
268 strncpy(gsms->text, sms->decoded, sizeof(gsms->text));
269
270 switch (sms->mti) {
271 case GSM340_SMS_SUBMIT_MS2SC:
272 /* MS is submitting a SMS */
273 rc = gsm340_rx_sms_submit(msg, sms, gsms);
274 break;
275 case GSM340_SMS_COMMAND_MS2SC:
276 case GSM340_SMS_DELIVER_REP_MS2SC:
277 DEBUGP(DSMS, "Unimplemented MTI 0x%02x\n", sms->mti);
278 break;
279 default:
280 DEBUGP(DSMS, "Undefined MTI 0x%02x\n", sms->mti);
281 break;
282 }
283
284out:
Harald Welte2cf161b2009-06-20 22:36:41 +0200285 talloc_free(gsms);
286 talloc_free(sms);
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000287
Harald Welte7e310b12009-03-30 20:56:32 +0000288 return rc;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000289}
290
Daniel Willmann9dfbf252008-12-29 03:24:29 +0000291static int gsm411_send_rp_ack(struct gsm_lchan *lchan, u_int8_t trans_id,
292 u_int8_t msg_ref)
Daniel Willmann471712b2008-12-29 01:54:02 +0000293{
294 struct msgb *msg = gsm411_msgb_alloc();
295 struct gsm48_hdr *gh;
296 struct gsm411_rp_hdr *rp;
297
298 msg->lchan = lchan;
299
300 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
Daniel Willmannaecbbed2008-12-29 03:45:50 +0000301 // Outgoing needs the highest bit set
302 gh->proto_discr = GSM48_PDISC_SMS | trans_id<<4 | 0x80;
303 gh->msg_type = GSM411_MT_CP_DATA;
Daniel Willmann471712b2008-12-29 01:54:02 +0000304
305 rp = (struct gsm411_rp_hdr *)msgb_put(msg, sizeof(*rp));
Daniel Willmannaecbbed2008-12-29 03:45:50 +0000306 rp->len = 2;
Daniel Willmann471712b2008-12-29 01:54:02 +0000307 rp->msg_type = GSM411_MT_RP_ACK_MT;
308 rp->msg_ref = msg_ref;
309
310 DEBUGP(DSMS, "TX: SMS RP ACK\n");
311
312 return gsm0411_sendmsg(msg);
313}
314
Daniel Willmann9dfbf252008-12-29 03:24:29 +0000315static int gsm411_send_rp_error(struct gsm_lchan *lchan, u_int8_t trans_id,
Harald Welte7e310b12009-03-30 20:56:32 +0000316 u_int8_t msg_ref, u_int8_t cause)
Daniel Willmann471712b2008-12-29 01:54:02 +0000317{
318 struct msgb *msg = gsm411_msgb_alloc();
319 struct gsm48_hdr *gh;
320 struct gsm411_rp_hdr *rp;
321
322 msg->lchan = lchan;
323
324 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
Daniel Willmannaecbbed2008-12-29 03:45:50 +0000325 // Outgoing needs the highest bit set
326 gh->proto_discr = GSM48_PDISC_SMS | trans_id<<4 | 0x80;
327 gh->msg_type = GSM411_MT_CP_DATA;
Daniel Willmann471712b2008-12-29 01:54:02 +0000328
329 rp = (struct gsm411_rp_hdr *)msgb_put(msg, sizeof(*rp));
330 rp->msg_type = GSM411_MT_RP_ERROR_MT;
331 rp->msg_ref = msg_ref;
Harald Welte7e310b12009-03-30 20:56:32 +0000332 msgb_tv_put(msg, 1, cause);
Daniel Willmann471712b2008-12-29 01:54:02 +0000333
Harald Welte7e310b12009-03-30 20:56:32 +0000334 DEBUGP(DSMS, "TX: SMS RP ERROR (cause %02d)\n", cause);
Daniel Willmann471712b2008-12-29 01:54:02 +0000335
336 return gsm0411_sendmsg(msg);
337}
338
Harald Welte7e310b12009-03-30 20:56:32 +0000339/* Receive a 04.11 TPDU inside RP-DATA / user data */
340static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm411_rp_hdr *rph,
341 u_int8_t src_len, u_int8_t *src,
342 u_int8_t dst_len, u_int8_t *dst,
343 u_int8_t tpdu_len, u_int8_t *tpdu)
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000344{
345 struct gsm48_hdr *gh = msgb_l3(msg);
Harald Welte7e310b12009-03-30 20:56:32 +0000346 u_int8_t trans_id = gh->proto_discr >> 4;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000347 int rc = 0;
348
Harald Welte7e310b12009-03-30 20:56:32 +0000349 if (src_len && src)
350 DEBUGP(DSMS, "RP-DATA (MO) with SRC ?!?\n");
351
352 if (!dst_len || !dst || !tpdu_len || !tpdu) {
353 DEBUGP(DSMS, "RP-DATA (MO) without DST or TPDU ?!?\n");
354 return -EIO;
355 }
356 msg->smsh = tpdu;
357
358 DEBUGP(DSMS, "DST(%u,%s)\n", dst_len, hexdump(dst, dst_len));
359 //return gsm411_send_rp_error(msg->lchan, trans_id, rph->msg_ref, rc);
360
361 rc = gsm340_rx_tpdu(msg);
362 if (rc == 0)
363 return gsm411_send_rp_ack(msg->lchan, trans_id, rph->msg_ref);
364 else if (rc > 0)
365 return gsm411_send_rp_error(msg->lchan, trans_id, rph->msg_ref, rc);
366 else
367 return rc;
368}
369
370/* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */
371static int gsm411_rx_rp_data(struct msgb *msg, struct gsm411_rp_hdr *rph)
372{
373 u_int8_t src_len, dst_len, rpud_len;
374 u_int8_t *src = NULL, *dst = NULL , *rp_ud = NULL;
375
376 /* in the MO case, this should always be zero length */
377 src_len = rph->data[0];
378 if (src_len)
379 src = &rph->data[1];
380
381 dst_len = rph->data[1+src_len];
382 if (dst_len)
383 dst = &rph->data[1+src_len+1];
384
385 rpud_len = rph->data[1+src_len+1+dst_len];
386 if (rpud_len)
387 rp_ud = &rph->data[1+src_len+1+dst_len+1];
388
389 DEBUGP(DSMS, "RX_RP-DATA: src_len=%u, dst_len=%u ud_len=%u\n", src_len, dst_len, rpud_len);
390 return gsm411_rx_rp_ud(msg, rph, src_len, src, dst_len, dst,
391 rpud_len, rp_ud);
392}
393
394static int gsm411_rx_cp_data(struct msgb *msg, struct gsm48_hdr *gh)
395{
Daniel Willmann471712b2008-12-29 01:54:02 +0000396 struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000397 u_int8_t msg_type = rp_data->msg_type & 0x07;
Harald Welte7e310b12009-03-30 20:56:32 +0000398 int rc = 0;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000399
400 switch (msg_type) {
401 case GSM411_MT_RP_DATA_MO:
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000402 DEBUGP(DSMS, "SMS RP-DATA (MO)\n");
Harald Welte7e310b12009-03-30 20:56:32 +0000403 rc = gsm411_rx_rp_data(msg, rp_data);
404 break;
405 case GSM411_MT_RP_ACK_MO:
406 /* Acnkowledgement to MT RP_DATA */
407 case GSM411_MT_RP_ERROR_MO:
408 /* Error in response to MT RP_DATA */
409 case GSM411_MT_RP_SMMA_MO:
410 /* MS tells us that it has memory for more SMS, we need
411 * to check if we have any pending messages for it and then
412 * transfer those */
413 DEBUGP(DSMS, "Unimplemented RP type 0x%02x\n", msg_type);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000414 break;
415 default:
Harald Welte7e310b12009-03-30 20:56:32 +0000416 DEBUGP(DSMS, "Invalid RP type 0x%02x\n", msg_type);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000417 break;
418 }
419
420 return rc;
421}
422
423int gsm0411_rcv_sms(struct msgb *msg)
424{
425 struct gsm48_hdr *gh = msgb_l3(msg);
426 u_int8_t msg_type = gh->msg_type;
427 int rc = 0;
428
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000429 switch(msg_type) {
430 case GSM411_MT_CP_DATA:
431 DEBUGP(DSMS, "SMS CP-DATA\n");
Harald Welte7e310b12009-03-30 20:56:32 +0000432 rc = gsm411_rx_cp_data(msg, gh);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000433 break;
434 case GSM411_MT_CP_ACK:
Daniel Willmannbb16e8e2008-12-29 03:53:50 +0000435 DEBUGP(DSMS, "SMS CP-ACK\n");
436 break;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000437 case GSM411_MT_CP_ERROR:
Daniel Willmannbb16e8e2008-12-29 03:53:50 +0000438 DEBUGP(DSMS, "SMS CP-ERROR, cause 0x%02x\n", gh->data[0]);
439 break;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000440 default:
441 DEBUGP(DSMS, "Unimplemented CP msg_type: 0x%02x\n", msg_type);
442 break;
443 }
444
445
446 return rc;
447}
448
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000449/* Test TPDU - 25c3 welcome */
Harald Welte8c2e36e2008-12-30 15:00:14 +0000450#if 0
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000451static u_int8_t tpdu_test[] = {
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000452 0x04, 0x04, 0x81, 0x32, 0x24, 0x00, 0x00, 0x80, 0x21, 0x92, 0x90, 0x32,
453 0x24, 0x40, 0x4D, 0xB2, 0xDA, 0x70, 0xD6, 0x9A, 0x97, 0xE5, 0xF6, 0xF4,
454 0xB8, 0x0C, 0x0A, 0xBB, 0xDD, 0xEF, 0xBA, 0x7B, 0x5C, 0x6E, 0x97, 0xDD,
455 0x74, 0x1D, 0x08, 0xCA, 0x2E, 0x87, 0xE7, 0x65, 0x50, 0x98, 0x4E, 0x2F,
456 0xBB, 0xC9, 0x20, 0x3A, 0xBA, 0x0C, 0x3A, 0x4E, 0x9B, 0x20, 0x7A, 0x98,
457 0xBD, 0x06, 0x85, 0xE9, 0xA0, 0x58, 0x4C, 0x37, 0x83, 0x81, 0xD2, 0x6E,
458 0xD0, 0x34, 0x1C, 0x66, 0x83, 0x62, 0x21, 0x90, 0xAE, 0x95, 0x02
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000459};
Harald Welte8c2e36e2008-12-30 15:00:14 +0000460#else
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000461/* Test TPDU - ALL YOUR */
462static u_int8_t tpdu_test[] = {
463 0x04, 0x04, 0x81, 0x32, 0x24, 0x00, 0x00, 0x80, 0x21, 0x03, 0x41, 0x24,
464 0x32, 0x40, 0x1F, 0x41, 0x26, 0x13, 0x94, 0x7D, 0x56, 0xA5, 0x20, 0x28,
465 0xF2, 0xE9, 0x2C, 0x82, 0x82, 0xD2, 0x22, 0x48, 0x58, 0x64, 0x3E, 0x9D,
466 0x47, 0x10, 0xF5, 0x09, 0xAA, 0x4E, 0x01
Daniel Willmanne2a728d2008-12-30 14:03:09 +0000467};
Harald Welte8c2e36e2008-12-30 15:00:14 +0000468#endif
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000469
470int gsm0411_send_sms(struct gsm_lchan *lchan, struct sms_deliver *sms)
471{
472 struct msgb *msg = gsm411_msgb_alloc();
473 struct gsm48_hdr *gh;
474 struct gsm411_rp_hdr *rp;
Holger Freytherca362a62009-01-04 21:05:01 +0000475 u_int8_t *data;
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000476
477 msg->lchan = lchan;
478
479 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
480 gh->proto_discr = GSM48_PDISC_SMS;
481 gh->msg_type = GSM411_MT_CP_DATA;
482
483 rp = (struct gsm411_rp_hdr *)msgb_put(msg, sizeof(*rp));
Daniel Willmanna3e29842008-12-29 16:03:54 +0000484 rp->len = sizeof(tpdu_test) + 10;
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000485 rp->msg_type = GSM411_MT_RP_DATA_MT;
486 rp->msg_ref = 42; /* FIXME: Choose randomly */
Daniel Willmannfad5d0d2008-12-29 16:04:14 +0000487 /* Hardcode OA for now */
Daniel Willmanna3e29842008-12-29 16:03:54 +0000488 data = (u_int8_t *)msgb_put(msg, 8);
489 data[0] = 0x07;
490 data[1] = 0x91;
491 data[2] = 0x44;
492 data[3] = 0x77;
493 data[4] = 0x58;
494 data[5] = 0x10;
495 data[6] = 0x06;
496 data[7] = 0x50;
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000497 data = (u_int8_t *)msgb_put(msg, 1);
498 data[0] = 0;
499
500 /* FIXME: Hardcoded for now */
Daniel Willmann4a1e8792008-12-29 06:23:56 +0000501 //smslen = gsm0411_tpdu_from_sms(tpdu, sms);
502
503 /* RPDU length */
504 data = (u_int8_t *)msgb_put(msg, 1);
505 data[0] = sizeof(tpdu_test);
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000506
507 data = (u_int8_t *)msgb_put(msg, sizeof(tpdu_test));
508
509 //memcpy(data, tpdu, smslen);
510 memcpy(data, tpdu_test, sizeof(tpdu_test));
511
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000512 DEBUGP(DSMS, "TX: SMS SUBMIT\n");
513
514 return gsm0411_sendmsg(msg);
515}