blob: 351a5fc506a9897dd5e159b001f438d13d7d8526 [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
Harald Welte87f5d632009-07-04 17:39:00 +020058static int gsm411_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
Harald Welte87f5d632009-07-04 17:39:00 +020068/* Prefix msg with a 04.08/04.11 CP header */
69static int gsm411_cp_sendmsg(struct msgb *msg, u_int8_t msg_type,
70 u_int8_t trans_id)
71{
72 struct gsm48_hdr *gh;
73
74 gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
75 /* Outgoing needs the highest bit set */
76 gh->proto_discr = GSM48_PDISC_SMS | trans_id<<4 | 0x80;
77 gh->msg_type = msg_type;
78
79 return gsm411_sendmsg(msg);
80}
81
82/* Prefix msg with a RP-DATA header and send as CP-DATA */
83static int gsm411_rp_sendmsg(struct msgb *msg, u_int8_t rp_msg_type,
84 u_int8_t rp_msg_ref, u_int8_t cp_trans_id)
85{
86 struct gsm411_rp_hdr *rp;
87
88 /* GSM 04.11 RP-DATA header */
89 rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp));
90 rp->len = msg->len;
91 rp->msg_type = rp_msg_type;
92 rp->msg_ref = rp_msg_ref; /* FIXME: Choose randomly */
93
94 return gsm411_cp_sendmsg(msg, GSM411_MT_CP_DATA, cp_trans_id);
95}
96
Daniel Willmanne0fbec82008-12-29 00:44:41 +000097
Holger Freytherca362a62009-01-04 21:05:01 +000098#if 0
Daniel Willmann6fe997e2008-12-29 04:20:41 +000099static u_int8_t gsm0411_tpdu_from_sms(u_int8_t *tpdu, struct sms_deliver *sms)
100{
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000101}
Holger Freytherca362a62009-01-04 21:05:01 +0000102#endif
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000103
Harald Welte7e310b12009-03-30 20:56:32 +0000104static unsigned long gsm340_validity_period(struct sms_submit *sms)
105{
106 u_int8_t vp;
107 unsigned long minutes;
108
109 switch (sms->vpf) {
110 case GSM340_TP_VPF_RELATIVE:
111 /* Chapter 9.2.3.12.1 */
112 vp = *(sms->vp);
113 if (vp <= 143)
114 minutes = vp + 1 * 5;
115 else if (vp <= 167)
116 minutes = 12*60 + (vp-143) * 30;
117 else if (vp <= 196)
118 minutes = vp-166 * 60 * 24;
119 else
120 minutes = vp-192 * 60 * 24 * 7;
121 break;
122 case GSM340_TP_VPF_ABSOLUTE:
123 /* Chapter 9.2.3.12.2 */
124 /* FIXME: like service center time stamp */
125 DEBUGP(DSMS, "VPI absolute not implemented yet\n");
126 break;
127 case GSM340_TP_VPF_ENHANCED:
128 /* Chapter 9.2.3.12.3 */
129 /* FIXME: implementation */
130 DEBUGP(DSMS, "VPI enhanced not implemented yet\n");
131 break;
132 }
133 return minutes;
134}
135
136/* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
137enum sms_alphabet gsm338_get_sms_alphabet(u_int8_t dcs)
138{
139 u_int8_t cgbits = dcs >> 4;
140 enum sms_alphabet alpha = DCS_NONE;
141
142 if ((cgbits & 0xc) == 0) {
143 if (cgbits & 2)
144 DEBUGP(DSMS, "Compressed SMS not supported yet\n");
145
146 switch (dcs & 3) {
147 case 0:
148 alpha = DCS_7BIT_DEFAULT;
149 break;
150 case 1:
151 alpha = DCS_8BIT_DATA;
152 break;
153 case 2:
154 alpha = DCS_UCS2;
155 break;
156 }
157 } else if (cgbits == 0xc || cgbits == 0xd)
158 alpha = DCS_7BIT_DEFAULT;
159 else if (cgbits == 0xe)
160 alpha = DCS_UCS2;
161 else if (cgbits == 0xf) {
162 if (dcs & 4)
163 alpha = DCS_8BIT_DATA;
164 else
165 alpha = DCS_7BIT_DEFAULT;
166 }
167
168 return alpha;
169}
170
171static int gsm340_rx_sms_submit(struct msgb *msg, struct sms_submit *sms,
172 struct gsm_sms *gsms)
173{
174 if (db_sms_store(gsms) != 0) {
175 DEBUGP(DSMS, "Failed to store SMS in Database\n");
Harald Welte2cf161b2009-06-20 22:36:41 +0200176 talloc_free(sms);
177 talloc_free(gsms);
Harald Welte7e310b12009-03-30 20:56:32 +0000178 return -EIO;
179 }
180 return 0;
181}
182
183/* process an incoming TPDU (called from RP-DATA) */
184static int gsm340_rx_tpdu(struct msgb *msg)
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000185{
186 u_int8_t *smsp = msgb_sms(msg);
187 struct sms_submit *sms;
Harald Welte7e310b12009-03-30 20:56:32 +0000188 struct gsm_sms *gsms;
189 u_int8_t da_len_bytes;
190 u_int8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
191 int rc = 0;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000192
Harald Welte2cf161b2009-06-20 22:36:41 +0200193 if (!tall_sms_ctx)
194 tall_sms_ctx = talloc_named_const(tall_bsc_ctx, 1,
195 "sms_submit");
196
197 sms = talloc(tall_sms_ctx, struct sms_submit);
Harald Welte7e310b12009-03-30 20:56:32 +0000198 if (!sms)
199 return -ENOMEM;
200 memset(sms, 0, sizeof(*sms));
201
Harald Welte2cf161b2009-06-20 22:36:41 +0200202 if (!tall_gsms_ctx)
203 tall_gsms_ctx = talloc_named_const(tall_bsc_ctx, 1,
204 "sms");
205
206 gsms = talloc(tall_gsms_ctx, struct gsm_sms);
Harald Welte7e310b12009-03-30 20:56:32 +0000207 if (!gsms) {
Harald Welte2cf161b2009-06-20 22:36:41 +0200208 talloc_free(sms);
Harald Welte7e310b12009-03-30 20:56:32 +0000209 return -ENOMEM;
210 }
211 memset(gsms, 0, sizeof(*gsms));
212
213 /* invert those fields where 0 means active/present */
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000214 sms->mti = *smsp & 0x03;
215 sms->mms = !!(*smsp & 0x04);
216 sms->vpf = (*smsp & 0x18) >> 3;
217 sms->sri = !!(*smsp & 0x20);
218 sms->udhi= !!(*smsp & 0x40);
219 sms->rp = !!(*smsp & 0x80);
220
221 smsp++;
222 sms->msg_ref = *smsp++;
223
Harald Welte7e310b12009-03-30 20:56:32 +0000224 /* length in bytes of the destination address */
225 da_len_bytes = 2 + *smsp/2 + *smsp%2;
226 if (da_len_bytes > 12) {
227 DEBUGP(DSMS, "Destination Address > 12 bytes ?!?\n");
228 rc = -EIO;
229 goto out;
230 }
Harald Welte3cfdb222009-06-12 02:42:11 +0800231 memset(address_lv, 0, sizeof(address_lv));
Harald Welte7e310b12009-03-30 20:56:32 +0000232 memcpy(address_lv, smsp, da_len_bytes);
233 /* mangle first byte to reflect length in bytes, not digits */
Harald Welte3cfdb222009-06-12 02:42:11 +0800234 address_lv[0] = da_len_bytes - 1;
Harald Welte7e310b12009-03-30 20:56:32 +0000235 /* convert to real number */
Harald Welte3cfdb222009-06-12 02:42:11 +0800236 decode_bcd_number(sms->dest_addr, sizeof(sms->dest_addr), address_lv, 1);
Harald Welte7e310b12009-03-30 20:56:32 +0000237
238 smsp += da_len_bytes;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000239
240 sms->pid = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000241
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000242 sms->dcs = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000243 sms->alphabet = gsm338_get_sms_alphabet(sms->dcs);
244
245 switch (sms->vpf) {
246 case GSM340_TP_VPF_RELATIVE:
247 sms->vp = smsp++;
248 break;
249 case GSM340_TP_VPF_ABSOLUTE:
250 case GSM340_TP_VPF_ENHANCED:
251 sms->vp = smsp;
252 smsp += 7;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000253 break;
254 default:
255 DEBUGP(DSMS, "SMS Validity period not implemented: 0x%02x\n",
256 sms->vpf);
257 }
258 sms->ud_len = *smsp++;
Harald Welte7e310b12009-03-30 20:56:32 +0000259 if (sms->ud_len)
260 sms->user_data = smsp;
261 else
262 sms->user_data = NULL;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000263
Harald Welte7e310b12009-03-30 20:56:32 +0000264 if (sms->ud_len) {
265 switch (sms->alphabet) {
266 case DCS_7BIT_DEFAULT:
267 gsm_7bit_decode(sms->decoded, smsp, sms->ud_len);
268 break;
269 case DCS_8BIT_DATA:
270 case DCS_UCS2:
271 case DCS_NONE:
272 memcpy(sms->decoded, sms->user_data, sms->ud_len);
273 break;
274 }
275 }
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000276
Harald Welte7e310b12009-03-30 20:56:32 +0000277 DEBUGP(DSMS, "SMS:\nMTI: 0x%02x, VPF: 0x%02x, MR: 0x%02x "
278 "PID: 0x%02x, DCS: 0x%02x, DA: %s, UserDataLength: 0x%02x "
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000279 "UserData: \"%s\"\n", sms->mti, sms->vpf, sms->msg_ref,
Harald Welte7e310b12009-03-30 20:56:32 +0000280 sms->pid, sms->dcs, sms->dest_addr, sms->ud_len,
281 sms->alphabet == DCS_7BIT_DEFAULT ? sms->decoded : hexdump(sms->user_data, sms->ud_len));
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000282
Harald Welte595ad7b2009-02-16 22:05:44 +0000283 dispatch_signal(SS_SMS, 0, sms);
Holger Freyther9b177762009-02-16 19:07:18 +0000284
Harald Welte7e310b12009-03-30 20:56:32 +0000285 gsms->sender = msg->lchan->subscr;
286 /* FIXME: sender refcount */
287
288 /* determine gsms->receiver based on dialled number */
289 gsms->receiver = subscr_get_by_extension(sms->dest_addr);
290 if (!gsms->receiver) {
291 rc = 1; /* cause 1: unknown subscriber */
292 goto out;
293 }
294
295 if (sms->user_data)
296 strncpy(gsms->text, sms->decoded, sizeof(gsms->text));
297
298 switch (sms->mti) {
299 case GSM340_SMS_SUBMIT_MS2SC:
300 /* MS is submitting a SMS */
301 rc = gsm340_rx_sms_submit(msg, sms, gsms);
302 break;
303 case GSM340_SMS_COMMAND_MS2SC:
304 case GSM340_SMS_DELIVER_REP_MS2SC:
305 DEBUGP(DSMS, "Unimplemented MTI 0x%02x\n", sms->mti);
306 break;
307 default:
308 DEBUGP(DSMS, "Undefined MTI 0x%02x\n", sms->mti);
309 break;
310 }
311
312out:
Harald Welte2cf161b2009-06-20 22:36:41 +0200313 talloc_free(gsms);
314 talloc_free(sms);
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000315
Harald Welte7e310b12009-03-30 20:56:32 +0000316 return rc;
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000317}
318
Daniel Willmann9dfbf252008-12-29 03:24:29 +0000319static int gsm411_send_rp_ack(struct gsm_lchan *lchan, u_int8_t trans_id,
320 u_int8_t msg_ref)
Daniel Willmann471712b2008-12-29 01:54:02 +0000321{
322 struct msgb *msg = gsm411_msgb_alloc();
Daniel Willmann471712b2008-12-29 01:54:02 +0000323
324 msg->lchan = lchan;
325
Daniel Willmann471712b2008-12-29 01:54:02 +0000326 DEBUGP(DSMS, "TX: SMS RP ACK\n");
327
Harald Welte87f5d632009-07-04 17:39:00 +0200328 return gsm411_rp_sendmsg(msg, GSM411_MT_RP_ACK_MT, msg_ref, trans_id);
Daniel Willmann471712b2008-12-29 01:54:02 +0000329}
330
Daniel Willmann9dfbf252008-12-29 03:24:29 +0000331static int gsm411_send_rp_error(struct gsm_lchan *lchan, u_int8_t trans_id,
Harald Welte7e310b12009-03-30 20:56:32 +0000332 u_int8_t msg_ref, u_int8_t cause)
Daniel Willmann471712b2008-12-29 01:54:02 +0000333{
334 struct msgb *msg = gsm411_msgb_alloc();
Daniel Willmann471712b2008-12-29 01:54:02 +0000335
336 msg->lchan = lchan;
337
Harald Welte7e310b12009-03-30 20:56:32 +0000338 msgb_tv_put(msg, 1, cause);
Daniel Willmann471712b2008-12-29 01:54:02 +0000339
Harald Welte7e310b12009-03-30 20:56:32 +0000340 DEBUGP(DSMS, "TX: SMS RP ERROR (cause %02d)\n", cause);
Daniel Willmann471712b2008-12-29 01:54:02 +0000341
Harald Welte87f5d632009-07-04 17:39:00 +0200342 return gsm411_rp_sendmsg(msg, GSM411_MT_RP_ERROR_MT, msg_ref, trans_id);
Daniel Willmann471712b2008-12-29 01:54:02 +0000343}
344
Harald Welte7e310b12009-03-30 20:56:32 +0000345/* Receive a 04.11 TPDU inside RP-DATA / user data */
346static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm411_rp_hdr *rph,
347 u_int8_t src_len, u_int8_t *src,
348 u_int8_t dst_len, u_int8_t *dst,
349 u_int8_t tpdu_len, u_int8_t *tpdu)
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000350{
351 struct gsm48_hdr *gh = msgb_l3(msg);
Harald Welte7e310b12009-03-30 20:56:32 +0000352 u_int8_t trans_id = gh->proto_discr >> 4;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000353 int rc = 0;
354
Harald Welte7e310b12009-03-30 20:56:32 +0000355 if (src_len && src)
356 DEBUGP(DSMS, "RP-DATA (MO) with SRC ?!?\n");
357
358 if (!dst_len || !dst || !tpdu_len || !tpdu) {
359 DEBUGP(DSMS, "RP-DATA (MO) without DST or TPDU ?!?\n");
360 return -EIO;
361 }
362 msg->smsh = tpdu;
363
364 DEBUGP(DSMS, "DST(%u,%s)\n", dst_len, hexdump(dst, dst_len));
365 //return gsm411_send_rp_error(msg->lchan, trans_id, rph->msg_ref, rc);
366
367 rc = gsm340_rx_tpdu(msg);
368 if (rc == 0)
369 return gsm411_send_rp_ack(msg->lchan, trans_id, rph->msg_ref);
370 else if (rc > 0)
371 return gsm411_send_rp_error(msg->lchan, trans_id, rph->msg_ref, rc);
372 else
373 return rc;
374}
375
376/* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */
377static int gsm411_rx_rp_data(struct msgb *msg, struct gsm411_rp_hdr *rph)
378{
379 u_int8_t src_len, dst_len, rpud_len;
380 u_int8_t *src = NULL, *dst = NULL , *rp_ud = NULL;
381
382 /* in the MO case, this should always be zero length */
383 src_len = rph->data[0];
384 if (src_len)
385 src = &rph->data[1];
386
387 dst_len = rph->data[1+src_len];
388 if (dst_len)
389 dst = &rph->data[1+src_len+1];
390
391 rpud_len = rph->data[1+src_len+1+dst_len];
392 if (rpud_len)
393 rp_ud = &rph->data[1+src_len+1+dst_len+1];
394
395 DEBUGP(DSMS, "RX_RP-DATA: src_len=%u, dst_len=%u ud_len=%u\n", src_len, dst_len, rpud_len);
396 return gsm411_rx_rp_ud(msg, rph, src_len, src, dst_len, dst,
397 rpud_len, rp_ud);
398}
399
400static int gsm411_rx_cp_data(struct msgb *msg, struct gsm48_hdr *gh)
401{
Daniel Willmann471712b2008-12-29 01:54:02 +0000402 struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000403 u_int8_t msg_type = rp_data->msg_type & 0x07;
Harald Welte7e310b12009-03-30 20:56:32 +0000404 int rc = 0;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000405
406 switch (msg_type) {
407 case GSM411_MT_RP_DATA_MO:
Daniel Willmanne0fbec82008-12-29 00:44:41 +0000408 DEBUGP(DSMS, "SMS RP-DATA (MO)\n");
Harald Welte7e310b12009-03-30 20:56:32 +0000409 rc = gsm411_rx_rp_data(msg, rp_data);
410 break;
411 case GSM411_MT_RP_ACK_MO:
412 /* Acnkowledgement to MT RP_DATA */
413 case GSM411_MT_RP_ERROR_MO:
414 /* Error in response to MT RP_DATA */
415 case GSM411_MT_RP_SMMA_MO:
416 /* MS tells us that it has memory for more SMS, we need
417 * to check if we have any pending messages for it and then
418 * transfer those */
419 DEBUGP(DSMS, "Unimplemented RP type 0x%02x\n", msg_type);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000420 break;
421 default:
Harald Welte7e310b12009-03-30 20:56:32 +0000422 DEBUGP(DSMS, "Invalid RP type 0x%02x\n", msg_type);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000423 break;
424 }
425
426 return rc;
427}
428
429int gsm0411_rcv_sms(struct msgb *msg)
430{
431 struct gsm48_hdr *gh = msgb_l3(msg);
432 u_int8_t msg_type = gh->msg_type;
433 int rc = 0;
434
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000435 switch(msg_type) {
436 case GSM411_MT_CP_DATA:
437 DEBUGP(DSMS, "SMS CP-DATA\n");
Harald Welte7e310b12009-03-30 20:56:32 +0000438 rc = gsm411_rx_cp_data(msg, gh);
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000439 break;
440 case GSM411_MT_CP_ACK:
Daniel Willmannbb16e8e2008-12-29 03:53:50 +0000441 DEBUGP(DSMS, "SMS CP-ACK\n");
442 break;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000443 case GSM411_MT_CP_ERROR:
Daniel Willmannbb16e8e2008-12-29 03:53:50 +0000444 DEBUGP(DSMS, "SMS CP-ERROR, cause 0x%02x\n", gh->data[0]);
445 break;
Daniel Willmann8b3390e2008-12-28 00:31:09 +0000446 default:
447 DEBUGP(DSMS, "Unimplemented CP msg_type: 0x%02x\n", msg_type);
448 break;
449 }
450
451
452 return rc;
453}
454
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000455/* Test TPDU - 25c3 welcome */
Harald Welte8c2e36e2008-12-30 15:00:14 +0000456#if 0
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000457static u_int8_t tpdu_test[] = {
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000458 0x04, 0x04, 0x81, 0x32, 0x24, 0x00, 0x00, 0x80, 0x21, 0x92, 0x90, 0x32,
459 0x24, 0x40, 0x4D, 0xB2, 0xDA, 0x70, 0xD6, 0x9A, 0x97, 0xE5, 0xF6, 0xF4,
460 0xB8, 0x0C, 0x0A, 0xBB, 0xDD, 0xEF, 0xBA, 0x7B, 0x5C, 0x6E, 0x97, 0xDD,
461 0x74, 0x1D, 0x08, 0xCA, 0x2E, 0x87, 0xE7, 0x65, 0x50, 0x98, 0x4E, 0x2F,
462 0xBB, 0xC9, 0x20, 0x3A, 0xBA, 0x0C, 0x3A, 0x4E, 0x9B, 0x20, 0x7A, 0x98,
463 0xBD, 0x06, 0x85, 0xE9, 0xA0, 0x58, 0x4C, 0x37, 0x83, 0x81, 0xD2, 0x6E,
464 0xD0, 0x34, 0x1C, 0x66, 0x83, 0x62, 0x21, 0x90, 0xAE, 0x95, 0x02
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000465};
Harald Welte8c2e36e2008-12-30 15:00:14 +0000466#else
Daniel Willmann3b3f0012008-12-30 13:56:46 +0000467/* Test TPDU - ALL YOUR */
468static u_int8_t tpdu_test[] = {
469 0x04, 0x04, 0x81, 0x32, 0x24, 0x00, 0x00, 0x80, 0x21, 0x03, 0x41, 0x24,
470 0x32, 0x40, 0x1F, 0x41, 0x26, 0x13, 0x94, 0x7D, 0x56, 0xA5, 0x20, 0x28,
471 0xF2, 0xE9, 0x2C, 0x82, 0x82, 0xD2, 0x22, 0x48, 0x58, 0x64, 0x3E, 0x9D,
472 0x47, 0x10, 0xF5, 0x09, 0xAA, 0x4E, 0x01
Daniel Willmanne2a728d2008-12-30 14:03:09 +0000473};
Harald Welte8c2e36e2008-12-30 15:00:14 +0000474#endif
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000475
476int gsm0411_send_sms(struct gsm_lchan *lchan, struct sms_deliver *sms)
477{
478 struct msgb *msg = gsm411_msgb_alloc();
Holger Freytherca362a62009-01-04 21:05:01 +0000479 u_int8_t *data;
Harald Welte87f5d632009-07-04 17:39:00 +0200480 u_int8_t msg_ref = 42;
481 u_int8_t trans_id = 23;
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000482
483 msg->lchan = lchan;
484
Harald Welte87f5d632009-07-04 17:39:00 +0200485 /* Hardcode Originating Address for now */
Daniel Willmanna3e29842008-12-29 16:03:54 +0000486 data = (u_int8_t *)msgb_put(msg, 8);
Harald Welte87f5d632009-07-04 17:39:00 +0200487 data[0] = 0x07; /* originator length == 7 */
488 data[1] = 0x91; /* type of number */
Daniel Willmanna3e29842008-12-29 16:03:54 +0000489 data[2] = 0x44;
490 data[3] = 0x77;
491 data[4] = 0x58;
492 data[5] = 0x10;
493 data[6] = 0x06;
494 data[7] = 0x50;
Harald Welte87f5d632009-07-04 17:39:00 +0200495
496 /* Hardcoded Destination Address */
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000497 data = (u_int8_t *)msgb_put(msg, 1);
Harald Welte87f5d632009-07-04 17:39:00 +0200498 data[0] = 0; /* destination length == 0 */
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000499
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
Harald Welte87f5d632009-07-04 17:39:00 +0200514 return gsm411_rp_sendmsg(msg, GSM411_MT_RP_DATA_MT, msg_ref, trans_id);
Daniel Willmann6fe997e2008-12-29 04:20:41 +0000515}