blob: 1b622b12b377c660cbc940f39cdeb89632cc0387 [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{
157 u_int8_t *smsp = msgb_sms(msg);
158 struct sms_submit *sms;
Harald Welte7e310b12009-03-30 20:56:32 +0000159 struct gsm_sms *gsms;
160 u_int8_t da_len_bytes;
161 u_int8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
162 int rc = 0;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000163
Harald Welte2cf161b2009-06-20 22:36:41 +0200164 if (!tall_sms_ctx)
165 tall_sms_ctx = talloc_named_const(tall_bsc_ctx, 1,
166 "sms_submit");
167
168 sms = talloc(tall_sms_ctx, struct sms_submit);
Harald Welte7e310b12009-03-30 20:56:32 +0000169 if (!sms)
170 return -ENOMEM;
171 memset(sms, 0, sizeof(*sms));
172
Harald Welte2cf161b2009-06-20 22:36:41 +0200173 if (!tall_gsms_ctx)
174 tall_gsms_ctx = talloc_named_const(tall_bsc_ctx, 1,
175 "sms");
176
177 gsms = talloc(tall_gsms_ctx, struct gsm_sms);
Harald Welte7e310b12009-03-30 20:56:32 +0000178 if (!gsms) {
Harald Welte2cf161b2009-06-20 22:36:41 +0200179 talloc_free(sms);
Harald Welte7e310b12009-03-30 20:56:32 +0000180 return -ENOMEM;
181 }
182 memset(gsms, 0, sizeof(*gsms));
183
184 /* invert those fields where 0 means active/present */
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000185 sms->mti = *smsp & 0x03;
186 sms->mms = !!(*smsp & 0x04);
187 sms->vpf = (*smsp & 0x18) >> 3;
188 sms->sri = !!(*smsp & 0x20);
189 sms->udhi= !!(*smsp & 0x40);
190 sms->rp = !!(*smsp & 0x80);
191
192 smsp++;
193 sms->msg_ref = *smsp++;
194
Harald Welte7e310b12009-03-30 20:56:32 +0000195 /* length in bytes of the destination address */
196 da_len_bytes = 2 + *smsp/2 + *smsp%2;
197 if (da_len_bytes > 12) {
198 DEBUGP(DSMS, "Destination Address > 12 bytes ?!?\n");
199 rc = -EIO;
200 goto out;
201 }
Harald Welte3cfdb222009-06-12 02:42:11 +0800202 memset(address_lv, 0, sizeof(address_lv));
Harald Welte7e310b12009-03-30 20:56:32 +0000203 memcpy(address_lv, smsp, da_len_bytes);
204 /* mangle first byte to reflect length in bytes, not digits */
Harald Welte3cfdb222009-06-12 02:42:11 +0800205 address_lv[0] = da_len_bytes - 1;
Harald Welte7e310b12009-03-30 20:56:32 +0000206 /* convert to real number */
Harald Welte3cfdb222009-06-12 02:42:11 +0800207 decode_bcd_number(sms->dest_addr, sizeof(sms->dest_addr), address_lv, 1);
Harald Welte7e310b12009-03-30 20:56:32 +0000208
209 smsp += da_len_bytes;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000210
211 sms->pid = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000212
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000213 sms->dcs = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000214 sms->alphabet = gsm338_get_sms_alphabet(sms->dcs);
215
216 switch (sms->vpf) {
217 case GSM340_TP_VPF_RELATIVE:
218 sms->vp = smsp++;
219 break;
220 case GSM340_TP_VPF_ABSOLUTE:
221 case GSM340_TP_VPF_ENHANCED:
222 sms->vp = smsp;
223 smsp += 7;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000224 break;
225 default:
226 DEBUGP(DSMS, "SMS Validity period not implemented: 0x%02x\n",
227 sms->vpf);
228 }
229 sms->ud_len = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000230 if (sms->ud_len)
231 sms->user_data = smsp;
232 else
233 sms->user_data = NULL;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000234
Harald Welte7e310b12009-03-30 20:56:32 +0000235 if (sms->ud_len) {
236 switch (sms->alphabet) {
237 case DCS_7BIT_DEFAULT:
238 gsm_7bit_decode(sms->decoded, smsp, sms->ud_len);
239 break;
240 case DCS_8BIT_DATA:
241 case DCS_UCS2:
242 case DCS_NONE:
243 memcpy(sms->decoded, sms->user_data, sms->ud_len);
244 break;
245 }
246 }
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000247
Harald Welte7e310b12009-03-30 20:56:32 +0000248 DEBUGP(DSMS, "SMS:\nMTI: 0x%02x, VPF: 0x%02x, MR: 0x%02x "
249 "PID: 0x%02x, DCS: 0x%02x, DA: %s, UserDataLength: 0x%02x "
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000250 "UserData: \"%s\"\n", sms->mti, sms->vpf, sms->msg_ref,
Harald Welte7e310b12009-03-30 20:56:32 +0000251 sms->pid, sms->dcs, sms->dest_addr, sms->ud_len,
252 sms->alphabet == DCS_7BIT_DEFAULT ? sms->decoded : hexdump(sms->user_data, sms->ud_len));
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000253
Harald Welte595ad7b2009-02-16 22:05:44 +0000254 dispatch_signal(SS_SMS, 0, sms);
Holger Freyther9b177762009-02-16 19:07:18 +0000255
Harald Welte7e310b12009-03-30 20:56:32 +0000256 gsms->sender = msg->lchan->subscr;
257 /* FIXME: sender refcount */
258
259 /* determine gsms->receiver based on dialled number */
260 gsms->receiver = subscr_get_by_extension(sms->dest_addr);
261 if (!gsms->receiver) {
262 rc = 1; /* cause 1: unknown subscriber */
263 goto out;
264 }
265
266 if (sms->user_data)
267 strncpy(gsms->text, sms->decoded, sizeof(gsms->text));
268
269 switch (sms->mti) {
270 case GSM340_SMS_SUBMIT_MS2SC:
271 /* MS is submitting a SMS */
272 rc = gsm340_rx_sms_submit(msg, sms, gsms);
273 break;
274 case GSM340_SMS_COMMAND_MS2SC:
275 case GSM340_SMS_DELIVER_REP_MS2SC:
276 DEBUGP(DSMS, "Unimplemented MTI 0x%02x\n", sms->mti);
277 break;
278 default:
279 DEBUGP(DSMS, "Undefined MTI 0x%02x\n", sms->mti);
280 break;
281 }
282
283out:
Harald Welte2cf161b2009-06-20 22:36:41 +0200284 talloc_free(gsms);
285 talloc_free(sms);
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000286
Harald Welte7e310b12009-03-30 20:56:32 +0000287 return rc;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000288}
289
Daniel Willmann9dfbf252008-12-29 03:24:29 +0000290static int gsm411_send_rp_ack(struct gsm_lchan *lchan, u_int8_t trans_id,
291 u_int8_t msg_ref)
Daniel Willmann471712b2008-12-29 01:54:02 +0000292{
293 struct msgb *msg = gsm411_msgb_alloc();
294 struct gsm48_hdr *gh;
295 struct gsm411_rp_hdr *rp;
296
297 msg->lchan = lchan;
298
299 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
Daniel Willmannaecbbed2008-12-29 03:45:50 +0000300 // Outgoing needs the highest bit set
301 gh->proto_discr = GSM48_PDISC_SMS | trans_id<<4 | 0x80;
302 gh->msg_type = GSM411_MT_CP_DATA;
Daniel Willmann471712b2008-12-29 01:54:02 +0000303
304 rp = (struct gsm411_rp_hdr *)msgb_put(msg, sizeof(*rp));
Daniel Willmannaecbbed2008-12-29 03:45:50 +0000305 rp->len = 2;
Daniel Willmann471712b2008-12-29 01:54:02 +0000306 rp->msg_type = GSM411_MT_RP_ACK_MT;
307 rp->msg_ref = msg_ref;
308
309 DEBUGP(DSMS, "TX: SMS RP ACK\n");
310
311 return gsm0411_sendmsg(msg);
312}
313
Daniel Willmann9dfbf252008-12-29 03:24:29 +0000314static int gsm411_send_rp_error(struct gsm_lchan *lchan, u_int8_t trans_id,
Harald Welte7e310b12009-03-30 20:56:32 +0000315 u_int8_t msg_ref, u_int8_t cause)
Daniel Willmann471712b2008-12-29 01:54:02 +0000316{
317 struct msgb *msg = gsm411_msgb_alloc();
318 struct gsm48_hdr *gh;
319 struct gsm411_rp_hdr *rp;
320
321 msg->lchan = lchan;
322
323 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
Daniel Willmannaecbbed2008-12-29 03:45:50 +0000324 // Outgoing needs the highest bit set
325 gh->proto_discr = GSM48_PDISC_SMS | trans_id<<4 | 0x80;
326 gh->msg_type = GSM411_MT_CP_DATA;
Daniel Willmann471712b2008-12-29 01:54:02 +0000327
328 rp = (struct gsm411_rp_hdr *)msgb_put(msg, sizeof(*rp));
329 rp->msg_type = GSM411_MT_RP_ERROR_MT;
330 rp->msg_ref = msg_ref;
Harald Welte7e310b12009-03-30 20:56:32 +0000331 msgb_tv_put(msg, 1, cause);
Daniel Willmann471712b2008-12-29 01:54:02 +0000332
Harald Welte7e310b12009-03-30 20:56:32 +0000333 DEBUGP(DSMS, "TX: SMS RP ERROR (cause %02d)\n", cause);
Daniel Willmann471712b2008-12-29 01:54:02 +0000334
335 return gsm0411_sendmsg(msg);
336}
337
Harald Welte7e310b12009-03-30 20:56:32 +0000338/* Receive a 04.11 TPDU inside RP-DATA / user data */
339static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm411_rp_hdr *rph,
340 u_int8_t src_len, u_int8_t *src,
341 u_int8_t dst_len, u_int8_t *dst,
342 u_int8_t tpdu_len, u_int8_t *tpdu)
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000343{
344 struct gsm48_hdr *gh = msgb_l3(msg);
Harald Welte7e310b12009-03-30 20:56:32 +0000345 u_int8_t trans_id = gh->proto_discr >> 4;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000346 int rc = 0;
347
Harald Welte7e310b12009-03-30 20:56:32 +0000348 if (src_len && src)
349 DEBUGP(DSMS, "RP-DATA (MO) with SRC ?!?\n");
350
351 if (!dst_len || !dst || !tpdu_len || !tpdu) {
352 DEBUGP(DSMS, "RP-DATA (MO) without DST or TPDU ?!?\n");
353 return -EIO;
354 }
355 msg->smsh = tpdu;
356
357 DEBUGP(DSMS, "DST(%u,%s)\n", dst_len, hexdump(dst, dst_len));
358 //return gsm411_send_rp_error(msg->lchan, trans_id, rph->msg_ref, rc);
359
360 rc = gsm340_rx_tpdu(msg);
361 if (rc == 0)
362 return gsm411_send_rp_ack(msg->lchan, trans_id, rph->msg_ref);
363 else if (rc > 0)
364 return gsm411_send_rp_error(msg->lchan, trans_id, rph->msg_ref, rc);
365 else
366 return rc;
367}
368
369/* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */
370static int gsm411_rx_rp_data(struct msgb *msg, struct gsm411_rp_hdr *rph)
371{
372 u_int8_t src_len, dst_len, rpud_len;
373 u_int8_t *src = NULL, *dst = NULL , *rp_ud = NULL;
374
375 /* in the MO case, this should always be zero length */
376 src_len = rph->data[0];
377 if (src_len)
378 src = &rph->data[1];
379
380 dst_len = rph->data[1+src_len];
381 if (dst_len)
382 dst = &rph->data[1+src_len+1];
383
384 rpud_len = rph->data[1+src_len+1+dst_len];
385 if (rpud_len)
386 rp_ud = &rph->data[1+src_len+1+dst_len+1];
387
388 DEBUGP(DSMS, "RX_RP-DATA: src_len=%u, dst_len=%u ud_len=%u\n", src_len, dst_len, rpud_len);
389 return gsm411_rx_rp_ud(msg, rph, src_len, src, dst_len, dst,
390 rpud_len, rp_ud);
391}
392
393static int gsm411_rx_cp_data(struct msgb *msg, struct gsm48_hdr *gh)
394{
Daniel Willmann471712b2008-12-29 01:54:02 +0000395 struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000396 u_int8_t msg_type = rp_data->msg_type & 0x07;
Harald Welte7e310b12009-03-30 20:56:32 +0000397 int rc = 0;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000398
399 switch (msg_type) {
400 case GSM411_MT_RP_DATA_MO:
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000401 DEBUGP(DSMS, "SMS RP-DATA (MO)\n");
Harald Welte7e310b12009-03-30 20:56:32 +0000402 rc = gsm411_rx_rp_data(msg, rp_data);
403 break;
404 case GSM411_MT_RP_ACK_MO:
405 /* Acnkowledgement to MT RP_DATA */
406 case GSM411_MT_RP_ERROR_MO:
407 /* Error in response to MT RP_DATA */
408 case GSM411_MT_RP_SMMA_MO:
409 /* MS tells us that it has memory for more SMS, we need
410 * to check if we have any pending messages for it and then
411 * transfer those */
412 DEBUGP(DSMS, "Unimplemented RP type 0x%02x\n", msg_type);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000413 break;
414 default:
Harald Welte7e310b12009-03-30 20:56:32 +0000415 DEBUGP(DSMS, "Invalid RP type 0x%02x\n", msg_type);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000416 break;
417 }
418
419 return rc;
420}
421
422int gsm0411_rcv_sms(struct msgb *msg)
423{
424 struct gsm48_hdr *gh = msgb_l3(msg);
425 u_int8_t msg_type = gh->msg_type;
426 int rc = 0;
427
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000428 switch(msg_type) {
429 case GSM411_MT_CP_DATA:
430 DEBUGP(DSMS, "SMS CP-DATA\n");
Harald Welte7e310b12009-03-30 20:56:32 +0000431 rc = gsm411_rx_cp_data(msg, gh);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000432 break;
433 case GSM411_MT_CP_ACK:
Daniel Willmannbb16e8e2008-12-29 03:53:50 +0000434 DEBUGP(DSMS, "SMS CP-ACK\n");
435 break;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000436 case GSM411_MT_CP_ERROR:
Daniel Willmannbb16e8e2008-12-29 03:53:50 +0000437 DEBUGP(DSMS, "SMS CP-ERROR, cause 0x%02x\n", gh->data[0]);
438 break;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000439 default:
440 DEBUGP(DSMS, "Unimplemented CP msg_type: 0x%02x\n", msg_type);
441 break;
442 }
443
444
445 return rc;
446}
447
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000448/* Test TPDU - 25c3 welcome */
Harald Welte8c2e36e2008-12-30 15:00:14 +0000449#if 0
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000450static u_int8_t tpdu_test[] = {
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000451 0x04, 0x04, 0x81, 0x32, 0x24, 0x00, 0x00, 0x80, 0x21, 0x92, 0x90, 0x32,
452 0x24, 0x40, 0x4D, 0xB2, 0xDA, 0x70, 0xD6, 0x9A, 0x97, 0xE5, 0xF6, 0xF4,
453 0xB8, 0x0C, 0x0A, 0xBB, 0xDD, 0xEF, 0xBA, 0x7B, 0x5C, 0x6E, 0x97, 0xDD,
454 0x74, 0x1D, 0x08, 0xCA, 0x2E, 0x87, 0xE7, 0x65, 0x50, 0x98, 0x4E, 0x2F,
455 0xBB, 0xC9, 0x20, 0x3A, 0xBA, 0x0C, 0x3A, 0x4E, 0x9B, 0x20, 0x7A, 0x98,
456 0xBD, 0x06, 0x85, 0xE9, 0xA0, 0x58, 0x4C, 0x37, 0x83, 0x81, 0xD2, 0x6E,
457 0xD0, 0x34, 0x1C, 0x66, 0x83, 0x62, 0x21, 0x90, 0xAE, 0x95, 0x02
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000458};
Harald Welte8c2e36e2008-12-30 15:00:14 +0000459#else
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000460/* Test TPDU - ALL YOUR */
461static u_int8_t tpdu_test[] = {
462 0x04, 0x04, 0x81, 0x32, 0x24, 0x00, 0x00, 0x80, 0x21, 0x03, 0x41, 0x24,
463 0x32, 0x40, 0x1F, 0x41, 0x26, 0x13, 0x94, 0x7D, 0x56, 0xA5, 0x20, 0x28,
464 0xF2, 0xE9, 0x2C, 0x82, 0x82, 0xD2, 0x22, 0x48, 0x58, 0x64, 0x3E, 0x9D,
465 0x47, 0x10, 0xF5, 0x09, 0xAA, 0x4E, 0x01
Daniel Willmanne2a728d2008-12-30 14:03:09 +0000466};
Harald Welte8c2e36e2008-12-30 15:00:14 +0000467#endif
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000468
469int gsm0411_send_sms(struct gsm_lchan *lchan, struct sms_deliver *sms)
470{
471 struct msgb *msg = gsm411_msgb_alloc();
472 struct gsm48_hdr *gh;
473 struct gsm411_rp_hdr *rp;
Holger Freytherca362a62009-01-04 21:05:01 +0000474 u_int8_t *data;
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000475
476 msg->lchan = lchan;
477
478 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
479 gh->proto_discr = GSM48_PDISC_SMS;
480 gh->msg_type = GSM411_MT_CP_DATA;
481
482 rp = (struct gsm411_rp_hdr *)msgb_put(msg, sizeof(*rp));
Daniel Willmanna3e29842008-12-29 16:03:54 +0000483 rp->len = sizeof(tpdu_test) + 10;
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000484 rp->msg_type = GSM411_MT_RP_DATA_MT;
485 rp->msg_ref = 42; /* FIXME: Choose randomly */
Daniel Willmannfad5d0d2008-12-29 16:04:14 +0000486 /* Hardcode OA for now */
Daniel Willmanna3e29842008-12-29 16:03:54 +0000487 data = (u_int8_t *)msgb_put(msg, 8);
488 data[0] = 0x07;
489 data[1] = 0x91;
490 data[2] = 0x44;
491 data[3] = 0x77;
492 data[4] = 0x58;
493 data[5] = 0x10;
494 data[6] = 0x06;
495 data[7] = 0x50;
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000496 data = (u_int8_t *)msgb_put(msg, 1);
497 data[0] = 0;
498
499 /* FIXME: Hardcoded for now */
Daniel Willmann4a1e8792008-12-29 06:23:56 +0000500 //smslen = gsm0411_tpdu_from_sms(tpdu, sms);
501
502 /* RPDU length */
503 data = (u_int8_t *)msgb_put(msg, 1);
504 data[0] = sizeof(tpdu_test);
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000505
506 data = (u_int8_t *)msgb_put(msg, sizeof(tpdu_test));
507
508 //memcpy(data, tpdu, smslen);
509 memcpy(data, tpdu_test, sizeof(tpdu_test));
510
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000511 DEBUGP(DSMS, "TX: SMS SUBMIT\n");
512
513 return gsm0411_sendmsg(msg);
514}