static void at_cmt_notify(GAtResult *result, gpointer user_data) { struct ofono_sms *sms = user_data; const char *hexpdu; long pdu_len; int tpdu_len; unsigned char pdu[176]; if (!at_parse_pdu_common(result, "+CMT:", &hexpdu, &tpdu_len)) { ofono_error("Unable to parse CMT notification"); return; } if (strlen(hexpdu) > sizeof(pdu) * 2) { ofono_error("Bad PDU length in CMT notification"); return; } DBG("Got new SMS Deliver PDU via CMT: %s, %d", hexpdu, tpdu_len); decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu); ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len); at_ack_delivery(sms); }
static void ril_sms_on_sim_cb(int ok, int total_length, int record, const unsigned char *sdata, int length, void *userdata) { struct ril_sms_on_sim_req *cbd = userdata; struct ril_sms *sd = cbd->sd; /* * It seems when reading EFsms RIL returns the whole record including * the first status byte therefore we ignore that as we are only * interested of the following pdu */ /* The first octect in the pdu contains the SMSC address length * which is the X following octects it reads. We add 1 octet to * the read length to take into account this read octet in order * to calculate the proper tpdu length. */ if (ok) { unsigned int smsc_len = sdata[1] + 1; ofono_sms_deliver_notify(sd->sms, sdata + 1, length - 1, length - smsc_len - 1); ril_request_delete_sms_om_sim(sd, cbd->record); } else { ofono_error("cannot read sms from sim"); } ril_sms_on_sim_req_free(cbd); }
static void ril_sms_notify(GRilIoChannel *io, guint ril_event, const void *data, guint len, void *user_data) { struct ril_sms *sd = user_data; GRilIoParser rilp; char *ril_pdu; int ril_pdu_len; unsigned int smsc_len; long ril_buf_len; guchar *ril_data; ril_pdu = NULL; ril_data = NULL; DBG("event: %d; data_len: %d", ril_event, len); grilio_parser_init(&rilp, data, len); ril_pdu = grilio_parser_get_utf8(&rilp); if (ril_pdu == NULL) goto error; ril_pdu_len = strlen(ril_pdu); DBG("ril_pdu_len is %d", ril_pdu_len); ril_data = decode_hex(ril_pdu, ril_pdu_len, &ril_buf_len, -1); if (ril_data == NULL) goto error; /* The first octect in the pdu contains the SMSC address length * which is the X following octects it reads. We add 1 octet to * the read length to take into account this read octet in order * to calculate the proper tpdu length. */ smsc_len = ril_data[0] + 1; ofono_info("sms received, smsc_len is %d", smsc_len); DBG("(%s)", ril_pdu); if (ril_event == RIL_UNSOL_RESPONSE_NEW_SMS) { /* Last parameter is 'tpdu_len' ( substract SMSC length ) */ ofono_sms_deliver_notify(sd->sms, ril_data, ril_buf_len, ril_buf_len - smsc_len); } else { GASSERT(ril_event == RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT); ofono_sms_status_notify(sd->sms, ril_data, ril_buf_len, ril_buf_len - smsc_len); } g_free(ril_pdu); g_free(ril_data); ril_ack_delivery(sd, TRUE); return; error: g_free(ril_pdu); g_free(ril_data); ril_ack_delivery(sd, FALSE); ofono_error("Unable to parse NEW_SMS notification"); }
static void received_msg_ind_cb(const GIsiMessage *msg, void *data) { struct ofono_sms *sms = data; struct sms_data *sd = ofono_sms_get_data(sms); struct sms_common tpdu; struct sms_addr addr; GIsiSubBlockIter iter; uint8_t pdu[176]; uint8_t sbcount; DBG(""); if (g_isi_msg_id(msg) != SMS_RECEIVED_MSG_IND) return; if (!g_isi_msg_data_get_byte(msg, 1, &sbcount)) return; for (g_isi_sb_iter_init_full(&iter, msg, 2, TRUE, sbcount); g_isi_sb_iter_is_valid(&iter); g_isi_sb_iter_next(&iter)) { switch (g_isi_sb_iter_get_id(&iter)) { case SMS_ADDRESS: if (!parse_sms_address(&iter, 4, &addr)) return; if (addr.type != SMS_SMSC_ADDRESS) return; break; case SMS_SB_TPDU: if (!parse_sms_tpdu(&iter, 4, &tpdu)) return; break; } } if (tpdu.data == NULL || addr.data == NULL || tpdu.len + addr.len > sizeof(pdu)) return; memcpy(pdu, addr.data, addr.len); memcpy(pdu + addr.len, tpdu.data, tpdu.len); /* 23.040 9.2.3.1 */ if ((tpdu.data[0] & 0x03) == 0x02) ofono_sms_status_notify(sms, pdu, tpdu.len + addr.len, tpdu.len); else ofono_sms_deliver_notify(sms, pdu, tpdu.len + addr.len, tpdu.len); send_deliver_report(sd->client, TRUE, NULL, NULL); }
static void at_cmgl_notify(GAtResult *result, gpointer user_data) { struct ofono_sms *sms = user_data; struct sms_data *data = ofono_sms_get_data(sms); GAtResultIter iter; const char *hexpdu; unsigned char pdu[176]; long pdu_len; int tpdu_len; int index; int status; char buf[16]; DBG(""); g_at_result_iter_init(&iter, result); while (g_at_result_iter_next(&iter, "+CMGL:")) { if (!g_at_result_iter_next_number(&iter, &index)) goto err; if (!g_at_result_iter_next_number(&iter, &status)) goto err; if (!g_at_result_iter_skip_next(&iter)) goto err; if (!g_at_result_iter_next_number(&iter, &tpdu_len)) goto err; /* Only MT messages */ if (status != 0 && status != 1) continue; hexpdu = g_at_result_pdu(result); DBG("Found an old SMS PDU: %s, with len: %d", hexpdu, tpdu_len); if (strlen(hexpdu) > sizeof(pdu) * 2) continue; decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu); ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len); /* We don't buffer SMS on the SIM/ME, send along a CMGD */ snprintf(buf, sizeof(buf), "AT+CMGD=%d", index); g_at_chat_send(data->chat, buf, none_prefix, at_cmgd_cb, NULL, NULL); } return; err: ofono_error("Unable to parse CMGL response"); }
static void at_cmgr_notify(GAtResult *result, gpointer user_data) { struct ofono_sms *sms = user_data; struct sms_data *data = ofono_sms_get_data(sms); GAtResultIter iter; const char *hexpdu; unsigned char pdu[176]; long pdu_len; int tpdu_len; DBG(""); g_at_result_iter_init(&iter, result); if (!g_at_result_iter_next(&iter, "+CMGR:")) goto err; if (!g_at_result_iter_skip_next(&iter)) goto err; if (!g_at_result_iter_skip_next(&iter)) goto err; if (!g_at_result_iter_next_number(&iter, &tpdu_len)) goto err; hexpdu = g_at_result_pdu(result); if (strlen(hexpdu) > sizeof(pdu) * 2) goto err; DBG("Got PDU: %s, with len: %d", hexpdu, tpdu_len); decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu); if (data->expect_sr) ofono_sms_status_notify(sms, pdu, pdu_len, tpdu_len); else ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len); return; err: ofono_error("Unable to parse CMGR response"); }
static void routing_ntf_cb(const GIsiMessage *msg, void *data) { struct ofono_sms *sms = data; struct sms_data *sd = ofono_sms_get_data(sms); struct sms_common tpdu; struct sms_addr addr; GIsiSubBlockIter iter; uint8_t pdu[176]; if (g_isi_msg_id(msg) != SMS_PP_ROUTING_NTF) return; for (g_isi_sb_iter_init(&iter, msg, 2); g_isi_sb_iter_is_valid(&iter); g_isi_sb_iter_next(&iter)) { if (g_isi_sb_iter_get_id(&iter) != SMS_GSM_TPDU) continue; if (!parse_gsm_tpdu(&iter, &addr, &tpdu)) return; } if (tpdu.data == NULL || addr.data == NULL || tpdu.len + addr.len > sizeof(pdu)) return; memcpy(pdu, addr.data, addr.len); memcpy(pdu + addr.len, tpdu.data, tpdu.len); /* 23.040 9.2.3.1 */ if ((tpdu.data[0] & 0x03) == 0x02) ofono_sms_status_notify(sms, pdu, tpdu.len + addr.len, tpdu.len); else ofono_sms_deliver_notify(sms, pdu, tpdu.len + addr.len, tpdu.len); send_gsm_deliver_report(sd->client, TRUE, NULL, NULL); }
static void ril_sms_notify(struct ril_msg *message, gpointer user_data) { struct ofono_sms *sms = user_data; struct sms_data *sd = ofono_sms_get_data(sms); struct parcel rilp; char *ril_pdu; int ril_pdu_len; unsigned int smsc_len; long ril_buf_len; guchar *ril_data; DBG("req: %d; data_len: %d", message->req, message->buf_len); switch (message->req) { case RIL_UNSOL_RESPONSE_NEW_SMS: case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: break; default: goto error; } ril_util_init_parcel(message, &rilp); ril_pdu = parcel_r_string(&rilp); if (ril_pdu == NULL) goto error; ril_pdu_len = strlen(ril_pdu); DBG("ril_pdu_len is %d", ril_pdu_len); ril_data = decode_hex(ril_pdu, ril_pdu_len, &ril_buf_len, -1); if (ril_data == NULL) goto error; /* The first octect in the pdu contains the SMSC address length * which is the X following octects it reads. We add 1 octet to * the read length to take into account this read octet in order * to calculate the proper tpdu length. */ smsc_len = ril_data[0] + 1; DBG("smsc_len is %d", smsc_len); g_ril_append_print_buf(sd->ril, "(%s)", ril_pdu); g_ril_print_unsol(sd->ril, message); if (message->req == RIL_UNSOL_RESPONSE_NEW_SMS) { /* Last parameter is 'tpdu_len' ( substract SMSC length ) */ ofono_sms_deliver_notify(sms, ril_data, ril_buf_len, ril_buf_len - smsc_len); } else if (message->req == RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT) { ofono_sms_status_notify(sms, ril_data, ril_buf_len, ril_buf_len - smsc_len); } ril_ack_delivery(sms); return; error: ofono_error("Unable to parse NEW_SMS notification"); }
static void ril_sms_notify(struct ril_msg *message, gpointer user_data) { struct ofono_sms *sms = user_data; struct sms_data *sd = ofono_sms_get_data(sms); struct parcel rilp; char *ril_pdu; int ril_pdu_len; unsigned int smsc_len; long ril_buf_len; guchar *ril_data; int request = RIL_REQUEST_SMS_ACKNOWLEDGE; int ret; DBG("req: %d; data_len: %d", message->req, (int) message->buf_len); if (message->req != RIL_UNSOL_RESPONSE_NEW_SMS) goto error; ril_util_init_parcel(message, &rilp); ril_pdu = parcel_r_string(&rilp); if (ril_pdu == NULL) goto error; ril_pdu_len = strlen(ril_pdu); DBG("ril_pdu_len is %d", ril_pdu_len); ril_data = decode_hex(ril_pdu, ril_pdu_len, &ril_buf_len, -1); if (ril_data == NULL) goto error; /* The first octect in the pdu contains the SMSC address length * which is the X following octects it reads. We add 1 octet to * the read length to take into account this read octet in order * to calculate the proper tpdu length. */ smsc_len = ril_data[0] + 1; DBG("smsc_len is %d", smsc_len); g_ril_append_print_buf(sd->ril, "(%s)", ril_pdu); g_ril_print_unsol(sd->ril, message); /* Last parameter is 'tpdu_len' ( substract SMSC length ) */ ofono_sms_deliver_notify(sms, ril_data, ril_buf_len, ril_buf_len - smsc_len); /* Re-use rilp, so initilize */ parcel_init(&rilp); parcel_w_int32(&rilp, 2); /* Number of int32 values in array */ parcel_w_int32(&rilp, 1); /* Successful receipt */ parcel_w_int32(&rilp, 0); /* error code */ /* TODO: should ACK be sent for either of the error cases? */ /* ACK the incoming NEW_SMS; ignore response so no cb needed */ ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, NULL, NULL, NULL); g_ril_append_print_buf(sd->ril, "(1,0)"); g_ril_print_request(sd->ril, ret, request); parcel_free(&rilp); return; error: ofono_error("Unable to parse NEW_SMS notification"); }