diff --git a/openbsc/include/openbsc/gsm_04_11.h b/openbsc/include/openbsc/gsm_04_11.h index 4f4535786..54b44c003 100644 --- a/openbsc/include/openbsc/gsm_04_11.h +++ b/openbsc/include/openbsc/gsm_04_11.h @@ -3,6 +3,21 @@ /* GSM TS 04.11 definitions */ +/* Chapter 5.2.3: SMC-CS states at the network side */ +enum gsm411_cp_state { + GSM411_CPS_IDLE = 0, + GSM411_CPS_MM_CONN_PENDING = 1, /* only MT ! */ + GSM411_CPS_WAIT_CP_ACK = 2, + GSM411_CPS_MM_ESTABLISHED = 3, +}; + +/* Chapter 6.2.2: SMR states at the network side */ +enum gsm411_rp_state { + GSM411_RPS_IDLE = 0, + GSM411_RPS_WAIT_FOR_RP_ACK = 1, + GSM411_RPS_WAIT_TO_TX_RP_ACK = 3, +}; + /* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */ #define GSM411_PDISC_SMS 0x09 @@ -73,6 +88,11 @@ enum gsm411_rp_cause { GSM411_RP_CAUSE_PROTOCOL_ERR = 111, }; +/* Chapter 10: Timers */ +#define GSM411_TMR_TR1M 40 /* 35 < x < 45 seconds */ +#define GSM411_TMR_TRAM 30 /* 25 < x < 35 seconds */ +#define GSM411_TMR_TR2M 15 /* 12 < x < 20 seconds */ + /* Chapter 8.2.1 */ struct gsm411_rp_hdr { u_int8_t len; @@ -184,7 +204,6 @@ struct sms_submit { #define GSM338_DCS_1111_CLASS2_SIM 2 #define GSM338_DCS_1111_CLASS3_TE 3 /* See TS 07.05 */ - /* SMS deliver PDU */ struct sms_deliver { u_int8_t mti:2; /* message type indicator */ diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 7ada2a13d..20e62c3c8 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -351,6 +351,11 @@ struct gsm_sms { struct gsm_subscriber *receiver; unsigned long validity_minutes; + unsigned char reply_path_req; + unsigned char status_rep_req; + unsigned char protocol_id; + unsigned char data_coding_scheme; + unsigned int header_len; unsigned char header[SMS_HDR_SIZE]; char text[SMS_TEXT_SIZE]; diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h index c51be8175..ad6fe35be 100644 --- a/openbsc/include/openbsc/transaction.h +++ b/openbsc/include/openbsc/transaction.h @@ -39,6 +39,7 @@ struct gsm_trans { struct gsm_mncc msg; /* stores setup/disconnect/release message */ } cc; struct { + int is_mt; /* is this a MO (0) or MT (1) transfer */ enum gsm411_cp_state cp_state; enum gsm411_rp_state rp_state; diff --git a/openbsc/src/db.c b/openbsc/src/db.c index 57c5c85f6..03b281a07 100644 --- a/openbsc/src/db.c +++ b/openbsc/src/db.c @@ -77,6 +77,11 @@ static char *create_stmts[] = { "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "sent TIMESTAMP, " + "valid_until TIMESTAMP, " + "reply_path_req NUMERIC NOT NULL, " + "status_rep_req NUMERIC NOT NULL, " + "protocol_id NUMERIC NOT NULL, " + "data_coding_scheme NUMERIC NOT NULL, " "sender_id NUMERIC NOT NULL, " "receiver_id NUMERIC NOT NULL, " "header BLOB, " @@ -458,13 +463,18 @@ int db_sms_store(struct gsm_sms *sms) dbi_conn_quote_string_copy(conn, (char *)sms->text, &q_text); dbi_conn_quote_binary_copy(conn, sms->header, sms->header_len, &q_header); + /* FIXME: correct validity period */ result = dbi_conn_queryf(conn, "INSERT INTO SMS " - "(created,sender_id,receiver_id,header,text) VALUES " - "(datetime('now'),%llu,%llu,%s,%s)", + "(created,sender_id,receiver_id,header,text," + "valid_until,reply_path_req,status_rep_req," + "protocol_id,data_coding_scheme) VALUES " + "(datetime('now'),%llu,%llu,%s,%s,%s,%u,%u,%u,%u)", sms->sender->id, sms->receiver ? sms->receiver->id : 0, - q_header, q_text); + q_header, q_text, '2222-2-2', sms->reply_path_req, + sms->status_rep_req, sms->protocol_id, + sms->data_coding_scheme); free(q_text); free(q_header); @@ -481,7 +491,8 @@ struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id) dbi_result result; long long unsigned int sender_id, receiver_id; struct gsm_sms *sms = malloc(sizeof(*sms)); - char *text; + const char *text; + const unsigned char *header; char buf[32]; if (!sms) { @@ -506,7 +517,16 @@ struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id) sprintf(buf, "%llu", receiver_id); sms->receiver = db_get_subscriber(net, GSM_SUBSCRIBER_ID, buf); - /* FIXME: fill header */ + /* FIXME: validity */ + sms->reply_path_req = dbi_result_get_uchar(result, "reply_path_req"); + sms->status_rep_req = dbi_result_get_uchar(result, "status_rep_req"); + sms->protocol_id = dbi_result_get_uchar(result, "protocol_id"); + sms->data_coding_scheme = dbi_result_get_uchar(result, + "data_coding_scheme"); + + sms->header_len = dbi_result_get_field_length(result, "header"); + header = dbi_result_get_binary(result, "header"); + memcpy(sms->header, header, sms->header_len); text = dbi_result_get_string(result, "text"); if (text) diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c index ed39f7928..1260eee1c 100644 --- a/openbsc/src/gsm_04_11.c +++ b/openbsc/src/gsm_04_11.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #define GSM411_ALLOC_SIZE 1024 #define GSM411_ALLOC_HEADROOM 128 @@ -49,6 +51,8 @@ static void *tall_sms_ctx; static void *tall_gsms_ctx; +static u_int32_t new_callref = 0x40000001; + struct msgb *gsm411_msgb_alloc(void) { return msgb_alloc_headroom(GSM411_ALLOC_SIZE, GSM411_ALLOC_HEADROOM, @@ -66,22 +70,33 @@ static int gsm411_sendmsg(struct msgb *msg) } /* Prefix msg with a 04.08/04.11 CP header */ -static int gsm411_cp_sendmsg(struct msgb *msg, u_int8_t msg_type, - u_int8_t trans_id) +static int gsm411_cp_sendmsg(struct msgb *msg, struct gsm_trans *trans, + u_int8_t msg_type) { struct gsm48_hdr *gh; gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh)); /* Outgoing needs the highest bit set */ - gh->proto_discr = GSM48_PDISC_SMS | trans_id<<4 | 0x80; + gh->proto_discr = trans->protocol | (trans->transaction_id<<4); gh->msg_type = msg_type; + /* assign the outgoing lchan */ + msg->lchan = trans->lchan; + + /* mobile originating */ + switch (gh->msg_type) { + case GSM411_MT_CP_DATA: + /* 5.2.3.1.2: enter MO-wait for CP-ack */ + trans->sms.cp_state = GSM411_CPS_WAIT_CP_ACK; + break; + } + return gsm411_sendmsg(msg); } /* Prefix msg with a RP-DATA header and send as CP-DATA */ -static int gsm411_rp_sendmsg(struct msgb *msg, u_int8_t rp_msg_type, - u_int8_t rp_msg_ref, u_int8_t cp_trans_id) +static int gsm411_rp_sendmsg(struct msgb *msg, struct gsm_trans *trans, + u_int8_t rp_msg_type, u_int8_t rp_msg_ref) { struct gsm411_rp_hdr *rp; @@ -91,10 +106,9 @@ static int gsm411_rp_sendmsg(struct msgb *msg, u_int8_t rp_msg_type, rp->msg_type = rp_msg_type; rp->msg_ref = rp_msg_ref; /* FIXME: Choose randomly */ - return gsm411_cp_sendmsg(msg, GSM411_MT_CP_DATA, cp_trans_id); + return gsm411_cp_sendmsg(msg, trans, GSM411_MT_CP_DATA); } - #if 0 static u_int8_t gsm0411_tpdu_from_sms(u_int8_t *tpdu, struct sms_deliver *sms) { @@ -178,6 +192,88 @@ static int gsm340_rx_sms_submit(struct msgb *msg, struct sms_submit *sms, return 0; } +static int gsm340_gen_oa(u_int8_t *oa, struct gsm_subscriber *subscr) +{ + int len = 0; + +} + +static u_int8_t bcdify(u_int8_t value) +{ + u_int8_t ret; + + ret = value % 10; + ret |= (value / 10) << 4; + + return ret; +} + +/* Generate 03.40 TP-SCTS */ +static void gsm340_gen_scts(u_int8_t *scts, time_t time) +{ + struct tm *tm = localtime(&time); + u_int8_t digit; + + *scts++ = bcdify(tm->tm_year % 100); + *scts++ = bcdify(tm->tm_mon); + *scts++ = bcdify(tm->tm_mday); + *scts++ = bcdify(tm->tm_hour); + *scts++ = bcdify(tm->tm_min); + *scts++ = bcdify(tm->tm_sec); + *scts++ = 0; /* FIXME: timezone */ +} + +static struct msgb *gsm340_gen_tpdu(struct gsm_sms *sms) +{ + struct msgb *msg = gsm411_msgb_alloc(); + u_int8_t *smsp; + u_int8_t oa[12]; /* max len per 03.40 */ + u_int8_t oa_len = 0; + + /* generate first octet with masked bits */ + smsp = msgb_put(msg, 1); + *smsp = GSM340_SMS_DELIVER_SC2MS; + if (0 /* FIXME: MMS */) + *smsp |= 0x04; + /* two bits empty */ + if (sms->status_rep_req) + *smsp |= 0x20; +#if 0 + if (sms->header_len) + *smsp |= 0x40; + if (sms-> + *smsp |= 0x80; +#endif + + /* generate originator address */ + smsp = msgb_put(msg, oa_len); + oa_len = gsm340_gen_oa(&oa, sms->sender); + memcpy(smsp, oa, oa_len); + + /* generate TP-PID */ + smsp = msgb_put(msg, 1); + *smsp = sms->protocol_id; + + /* generate TP-DCS */ + smsp = msgb_put(msg, 1); + *smsp = sms->data_coding_scheme; + + /* generate TP-SCTS */ + smsp = msgb_put(msg, 7); + gsm340_gen_scts(smsp, time(NULL)); +#if 0 + /* generate TP-UDL */ + smsp = msgb_put(msg, 1); + *smsp = ud_len; + + /* generate TP-UD */ + smsp = msgb_put(msg, ud_len); + memcpy(smsp, FIXME, ud_len); +#endif + + return msg; +} + /* process an incoming TPDU (called from RP-DATA) * return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */ static int gsm340_rx_tpdu(struct msgb *msg) @@ -214,9 +310,9 @@ static int gsm340_rx_tpdu(struct msgb *msg) sms->mti = *smsp & 0x03; sms->mms = !!(*smsp & 0x04); sms->vpf = (*smsp & 0x18) >> 3; - sms->srr = !!(*smsp & 0x20); - sms->udhi= !!(*smsp & 0x40); - sms->rp = !!(*smsp & 0x80); + sms->srr = (*smsp & 0x20); + sms->udhi= (*smsp & 0x40); + sms->rp = (*smsp & 0x80); smsp++; sms->msg_ref = *smsp++; @@ -298,8 +394,10 @@ static int gsm340_rx_tpdu(struct msgb *msg) goto out; } - if (sms->user_data) + if (sms->user_data) { + gsms->header_len = sms->ud_len; memcpy(gsms->header, sms->user_data, sms->ud_len); + } if (sms->decoded) strncpy(gsms->text, sms->decoded, sizeof(gsms->text)); @@ -330,40 +428,35 @@ out: return rc; } -static int gsm411_send_rp_ack(struct gsm_lchan *lchan, u_int8_t trans_id, - u_int8_t msg_ref) +static int gsm411_send_rp_ack(struct gsm_trans *trans, u_int8_t msg_ref) { struct msgb *msg = gsm411_msgb_alloc(); - msg->lchan = lchan; - DEBUGP(DSMS, "TX: SMS RP ACK\n"); - return gsm411_rp_sendmsg(msg, GSM411_MT_RP_ACK_MT, msg_ref, trans_id); + return gsm411_rp_sendmsg(msg, trans, GSM411_MT_RP_ACK_MT, msg_ref); } -static int gsm411_send_rp_error(struct gsm_lchan *lchan, u_int8_t trans_id, - u_int8_t msg_ref, u_int8_t cause) +static int gsm411_send_rp_error(struct gsm_trans *trans, + u_int8_t msg_ref, u_int8_t cause) { struct msgb *msg = gsm411_msgb_alloc(); - msg->lchan = lchan; - msgb_tv_put(msg, 1, cause); DEBUGP(DSMS, "TX: SMS RP ERROR (cause %02d)\n", cause); - return gsm411_rp_sendmsg(msg, GSM411_MT_RP_ERROR_MT, msg_ref, trans_id); + return gsm411_rp_sendmsg(msg, trans, GSM411_MT_RP_ERROR_MT, msg_ref); } /* Receive a 04.11 TPDU inside RP-DATA / user data */ -static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm411_rp_hdr *rph, +static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans, + struct gsm411_rp_hdr *rph, u_int8_t src_len, u_int8_t *src, u_int8_t dst_len, u_int8_t *dst, u_int8_t tpdu_len, u_int8_t *tpdu) { struct gsm48_hdr *gh = msgb_l3(msg); - u_int8_t trans_id = gh->proto_discr >> 4; int rc = 0; if (src_len && src) @@ -371,7 +464,7 @@ static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm411_rp_hdr *rph, if (!dst_len || !dst || !tpdu_len || !tpdu) { DEBUGP(DSMS, "RP-DATA (MO) without DST or TPDU ?!?\n"); - gsm411_send_rp_error(msg->lchan, trans_id, rph->msg_ref, + gsm411_send_rp_error(trans, rph->msg_ref, GSM411_RP_CAUSE_INV_MAND_INF); return -EIO; } @@ -381,15 +474,16 @@ static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm411_rp_hdr *rph, rc = gsm340_rx_tpdu(msg); if (rc == 0) - return gsm411_send_rp_ack(msg->lchan, trans_id, rph->msg_ref); + return gsm411_send_rp_ack(trans, rph->msg_ref); else if (rc > 0) - return gsm411_send_rp_error(msg->lchan, trans_id, rph->msg_ref, rc); + return gsm411_send_rp_error(trans, rph->msg_ref, rc); else return rc; } /* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */ -static int gsm411_rx_rp_data(struct msgb *msg, struct gsm411_rp_hdr *rph) +static int gsm411_rx_rp_data(struct msgb *msg, struct gsm_trans *trans, + struct gsm411_rp_hdr *rph) { u_int8_t src_len, dst_len, rpud_len; u_int8_t *src = NULL, *dst = NULL , *rp_ud = NULL; @@ -409,12 +503,13 @@ static int gsm411_rx_rp_data(struct msgb *msg, struct gsm411_rp_hdr *rph) DEBUGP(DSMS, "RX_RP-DATA: src_len=%u, dst_len=%u ud_len=%u\n", src_len, dst_len, rpud_len); - return gsm411_rx_rp_ud(msg, rph, src_len, src, dst_len, dst, + return gsm411_rx_rp_ud(msg, trans, rph, src_len, src, dst_len, dst, rpud_len, rp_ud); } -static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm411_rp_hdr *rph) +static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm_trans *trans, + struct gsm411_rp_hdr *rph) { /* Acnkowledgement to MT RP_DATA, i.e. the MS confirms it * successfully received a SMS. We can now safely mark it as @@ -425,25 +520,41 @@ static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm411_rp_hdr *rph) } -static int gsm411_rx_rp_error(struct msgb *msg, struct gsm411_rp_hdr *rph) +static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans, + struct gsm411_rp_hdr *rph) { + u_int8_t cause_len = rph->data[0]; + u_int8_t cause = rph->data[1]; + /* Error in response to MT RP_DATA, i.e. the MS did not * successfully receive the SMS. We need to investigate * the cause and take action depending on it */ + DEBUGP(DSMS, "RX SMS RP-ERROR Cause=0x%02x\n", cause); + /* we need to look-up the transaction based on rph->msg_ref to * identify which particular RP_DATA/SMS-submit failed */ + return 0; } -static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm411_rp_hdr *rph) +static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm_trans *trans, + struct gsm411_rp_hdr *rph) { + int rc; + /* MS tells us that it has memory for more SMS, we need * to check if we have any pending messages for it and then * transfer those */ + + rc = gsm411_send_rp_ack(trans, rph->msg_ref); + trans->sms.rp_state = GSM411_RPS_IDLE; + + return rc; } -static int gsm411_rx_cp_data(struct msgb *msg, struct gsm48_hdr *gh) +static int gsm411_rx_cp_data(struct msgb *msg, struct gsm48_hdr *gh, + struct gsm_trans *trans) { struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data; u_int8_t msg_type = rp_data->msg_type & 0x07; @@ -451,51 +562,129 @@ static int gsm411_rx_cp_data(struct msgb *msg, struct gsm48_hdr *gh) switch (msg_type) { case GSM411_MT_RP_DATA_MO: - DEBUGP(DSMS, "SMS RP-DATA (MO)\n"); - rc = gsm411_rx_rp_data(msg, rp_data); + DEBUGP(DSMS, "RX SMS RP-DATA (MO)\n"); + /* start TR2N and enter 'wait to send RP-ACK state' */ + trans->sms.rp_state = GSM411_RPS_WAIT_TO_TX_RP_ACK; + rc = gsm411_rx_rp_data(msg, trans, rp_data); break; case GSM411_MT_RP_ACK_MO: - rc = gsm411_rx_rp_ack(msg, rp_data); - break; - case GSM411_MT_RP_ERROR_MO: - rc = gsm411_rx_rp_error(msg, rp_data); + DEBUGP(DSMS,"RX SMS RP-ACK (MO)\n"); + rc = gsm411_rx_rp_ack(msg, trans, rp_data); break; case GSM411_MT_RP_SMMA_MO: - rc = gsm411_rx_rp_smma(msg, rp_data); - DEBUGP(DSMS, "Unimplemented RP type 0x%02x\n", msg_type); + DEBUGP(DSMS, "RX SMS RP-SMMA\n"); + /* start TR2N and enter 'wait to send RP-ACK state' */ + trans->sms.rp_state = GSM411_RPS_WAIT_TO_TX_RP_ACK; + rc = gsm411_rx_rp_smma(msg, trans, rp_data); + break; + case GSM411_MT_RP_ERROR_MO: + rc = gsm411_rx_rp_error(msg, trans, rp_data); break; default: - /* FIXME: send GSM411_CP_CAUSE_MSGTYPE_NOTEXIST */ DEBUGP(DSMS, "Invalid RP type 0x%02x\n", msg_type); + rc = gsm411_send_rp_error(trans, rp_data->msg_ref, + GSM411_RP_CAUSE_MSGTYPE_NOTEXIST); break; } return rc; } +/* send CP-ACK to given transaction */ +static int gsm411_tx_cp_ack(struct gsm_trans *trans) +{ + struct msgb *msg = gsm411_msgb_alloc(); + + return gsm411_cp_sendmsg(msg, trans, GSM411_MT_CP_ACK); +} + +static int gsm411_tx_cp_error(struct gsm_trans *trans, u_int8_t cause) +{ + struct msgb *msg = gsm411_msgb_alloc(); + u_int8_t *causep; + + cause = msgb_put(msg, 1); + *causep = cause; + + return gsm411_cp_sendmsg(msg, trans, GSM411_MT_CP_ERROR); +} + +/* Entry point for incoming GSM48_PDISC_SMS from abis_rsl.c */ int gsm0411_rcv_sms(struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); u_int8_t msg_type = gh->msg_type; + u_int8_t transaction_id = ((gh->proto_discr >> 4) ^ 0x8); /* flip */ + struct gsm_lchan *lchan = msg->lchan; + struct gsm_trans *trans; int rc = 0; + if (!lchan->subscr) + return -EIO; + /* FIXME: send some error message */ + + trans = trans_find_by_id(lchan->subscr, GSM48_PDISC_SMS, + transaction_id); + if (!trans) { + DEBUGP(DSMS, "Unknown transaction ID %x, " + "creating new trans\n", transaction_id); + trans = trans_alloc(lchan->subscr, GSM48_PDISC_SMS, + transaction_id, new_callref++); + if (!trans) { + DEBUGP(DSMS, "No memory for trans\n"); + /* FIXME: send some error message */ + return -ENOMEM; + } + trans->sms.cp_state = GSM411_CPS_IDLE; + trans->sms.rp_state = GSM411_RPS_IDLE; + trans->sms.is_mt = 0; + + trans->lchan = lchan; + use_lchan(lchan); + } + switch(msg_type) { case GSM411_MT_CP_DATA: - DEBUGP(DSMS, "SMS CP-DATA\n"); - rc = gsm411_rx_cp_data(msg, gh); + DEBUGP(DSMS, "RX SMS CP-DATA\n"); + if (!trans->sms.is_mt) { + /* 5.2.3.1.3: MO state exists when SMC has received + * CP-DATA, including sending of the assoc. CP-ACK */ + trans->sms.cp_state = GSM411_CPS_MM_ESTABLISHED; + } + + rc = gsm411_rx_cp_data(msg, gh, trans); + /* Send CP-ACK or CP-ERORR in response */ + if (rc < 0) { + rc = gsm411_tx_cp_error(trans, GSM411_CP_CAUSE_NET_FAIL); + } else + rc = gsm411_tx_cp_ack(trans); break; case GSM411_MT_CP_ACK: - DEBUGP(DSMS, "SMS CP-ACK\n"); + /* previous CP-DATA in this transaction was confirmed */ + DEBUGP(DSMS, "RX SMS CP-ACK\n"); + if (!trans->sms.is_mt) { + /* 5.2.3.1.3: MO state exists when SMC has received + * CP-ACK */ + trans->sms.cp_state = GSM411_CPS_MM_ESTABLISHED; + /* FIXME: we have sont one CP-DATA, which was now + * acknowledged. Check if we want to transfer more, + * i.e. multi-part message */ + trans->sms.cp_state = GSM411_CPS_IDLE; + trans_free(trans); + } break; case GSM411_MT_CP_ERROR: - DEBUGP(DSMS, "SMS CP-ERROR, cause 0x%02x\n", gh->data[0]); + DEBUGP(DSMS, "RX SMS CP-ERROR, cause 0x%02x\n", gh->data[0]); + trans->sms.cp_state = GSM411_CPS_IDLE; + trans_free(trans); break; default: - DEBUGP(DSMS, "Unimplemented CP msg_type: 0x%02x\n", msg_type); + DEBUGP(DSMS, "RX Unimplemented CP msg_type: 0x%02x\n", msg_type); + rc = gsm411_tx_cp_error(trans, GSM411_CP_CAUSE_MSGTYPE_NOTEXIST); + trans_free(trans); break; } - return rc; } @@ -523,12 +712,15 @@ static u_int8_t tpdu_test[] = { int gsm0411_send_sms(struct gsm_lchan *lchan, struct sms_deliver *sms) { struct msgb *msg = gsm411_msgb_alloc(); + struct gsm_trans *trans; u_int8_t *data; u_int8_t msg_ref = 42; u_int8_t trans_id = 23; msg->lchan = lchan; + /* FIXME: allocate trans */ + /* Hardcode Originating Address for now */ data = (u_int8_t *)msgb_put(msg, 8); data[0] = 0x07; /* originator length == 7 */ @@ -558,5 +750,25 @@ int gsm0411_send_sms(struct gsm_lchan *lchan, struct sms_deliver *sms) DEBUGP(DSMS, "TX: SMS SUBMIT\n"); - return gsm411_rp_sendmsg(msg, GSM411_MT_RP_DATA_MT, msg_ref, trans_id); + return gsm411_rp_sendmsg(msg, trans, GSM411_MT_RP_DATA_MT, msg_ref); + /* FIXME: enter 'wait for RP-ACK' state, start TR1N */ } + + +#if 0 +{ + struct sms_deliver *smsd; + + smsd->mti = GSM340_SMS_DELIVER_SC2MS; + smsd->mms = 0; /* FIXME: determine if there are more */ + smsd->rp = FIXME; + smsd->udhi = FIXME; + smsd->sri = 1; + smsd->oa = FIXME; + smsd->pid = FIXME; + smsd->dcs = FIXME; + smsd->scts = FIXME; + smsd->ud_len = FIXME; + smsd->ud = FIXME; +} +#endif