Beispiel #1
0
static void u8500_online(struct ofono_modem *modem, ofono_bool_t online,
				ofono_modem_online_cb_t cb, void *data)
{
	struct isi_data *isi = ofono_modem_get_data(modem);
	struct isi_cb_data *cbd = isi_cb_data_new(modem, cb, data);
	const uint8_t req[] = {
		MCE_RF_STATE_REQ,
		online ? MCE_RF_ON : MCE_RF_OFF,
		0x00
	};

	DBG("(%p) with %s", modem, isi->ifname);

	if (cbd == NULL || isi == NULL)
		goto error;

	if (g_isi_client_send_with_timeout(isi->client, req, sizeof(req),
				MTC_STATE_REQ_TIMEOUT,
				mce_state_cb, cbd, NULL)) {
		isi->online = online;
		return;
	}

error:
	CALLBACK_WITH_FAILURE(cb, data);
	g_free(cbd);
}
Beispiel #2
0
static void u8500_query_revision(struct ofono_devinfo *info,
				ofono_devinfo_query_cb_t cb,
				void *data)
{
	struct devinfo_data *dev = ofono_devinfo_get_data(info);
	struct isi_cb_data *cbd = isi_cb_data_new(dev, cb, data);
	const unsigned char msg[] = {
		INFO_SERIAL_NUMBER_READ_REQ,
		0x00, 0x00,
		0x00, 0x00, 0x00, 0x01, /* M_INFO_MODEMSW */
		0x00, 0x00
	};
	DBG("");

	if (cbd == NULL || dev == NULL)
		goto error;

	if (g_isi_client_send(dev->client, msg, sizeof(msg),
				u8500_info_resp_cb, cbd, g_free))
		return;


error:
	CALLBACK_WITH_FAILURE(cb, "", data);
	g_free(cbd);
}
Beispiel #3
0
static void isi_bearer_set(struct ofono_sms *sms, int bearer,
				ofono_sms_bearer_set_cb_t cb, void *data)
{
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct isi_cb_data *cbd = isi_cb_data_new(sms, cb, data);
	const uint8_t msg[] = {
		SMS_SETTINGS_UPDATE_REQ,
		SMS_SETTING_TYPE_ROUTE,
		1,		/* Subblock count */
		ISI_16BIT(SMS_SB_ROUTE_INFO),
		ISI_16BIT(8),	/* Subblock length */
		bearer_to_cs_pref(bearer),	/* CS priority */
		bearer_to_ps_pref(bearer),	/* PS priority */
		0, 0,
	};

	if (cbd == NULL)
		goto error;

	if (g_isi_client_send(sd->client, msg, sizeof(msg), bearer_set_resp_cb,
				cbd, g_free))
		return;

error:
	CALLBACK_WITH_FAILURE(cb, data);
	g_free(cbd);
}
Beispiel #4
0
static void isi_sca_query(struct ofono_sms *sms,
				ofono_sms_sca_query_cb_t cb, void *data)
{
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct isi_cb_data *cbd = isi_cb_data_new(sms, cb, data);

	if (cbd == NULL || sd->sim == NULL)
		goto error;

	if (sca_sim_query(sd->sim, cbd, g_free))
		return;

error:
	CALLBACK_WITH_FAILURE(cb, NULL, data);
	g_free(cbd);
}
Beispiel #5
0
static void isi_sca_set(struct ofono_sms *sms,
			const struct ofono_phone_number *sca,
			ofono_sms_sca_set_cb_t cb, void *data)
{
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct isi_cb_data *cbd = isi_cb_data_new(sms, cb, data);

	if (cbd == NULL || sd->sim == NULL)
		goto error;

	if (sca_sim_set(sd->sim, &sd->params, sca, cbd, g_free))
		return;

error:
	CALLBACK_WITH_FAILURE(cb, data);
	g_free(cbd);
}
Beispiel #6
0
static void isi_read_file_info(struct ofono_sim *sim, int fileid,
                               ofono_sim_file_info_cb_t cb, void *data)
{
    int i;
    static struct file_info const info[] = {
        { SIM_EFSPN_FILEID, 17, 0, 0, { 0x0f, 0xff, 0xff } },
        { SIM_EF_ICCID_FILEID, 10, 0, 0, { 0x0f, 0xff, 0xff } },
    };
    int N = sizeof(info) / sizeof(info[0]);
    struct isi_cb_data *cbd;

    for (i = 0; i < N; i++) {
        if (fileid == info[i].fileid) {
            cbd = isi_cb_data_new((void *)&info[i], cb, data);
            g_idle_add(fake_file_info, cbd);
            return;
        }
    }

    DBG("Not implemented (fileid = %04x)", fileid);
    CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL, data);
}
Beispiel #7
0
static void isi_bearer_query(struct ofono_sms *sms,
				ofono_sms_bearer_query_cb_t cb, void *data)
{
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct isi_cb_data *cbd = isi_cb_data_new(sms, cb, data);
	const uint8_t msg[] = {
		SMS_SETTINGS_READ_REQ,
		SMS_SETTING_TYPE_ROUTE,
		0,
	};

	DBG("");

	if (cbd == NULL)
		goto error;

	if (g_isi_client_send(sd->client, msg, sizeof(msg), bearer_query_resp_cb,
				cbd, g_free))
		return;

error:
	CALLBACK_WITH_FAILURE(cb, 0, data);
	g_free(cbd);
}
Beispiel #8
0
static void isi_submit(struct ofono_sms *sms, unsigned char *pdu,
			int pdu_len, int tpdu_len, int mms,
			ofono_sms_submit_cb_t cb, void *data)
{
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct isi_cb_data *cbd = isi_cb_data_new(sms, cb, data);

	if (cbd == NULL)
		goto error;

	if (ISI_VERSION_AT_LEAST(&sd->version, 9, 1)) {
		if (submit_tpdu(sd->client, pdu, pdu_len, tpdu_len, mms,
				cbd, g_free))
			return;
	} else {
		if (submit_gsm_tpdu(sd->client, pdu, pdu_len, tpdu_len, mms,
					cbd, g_free))
			return;
	}

error:
	CALLBACK_WITH_FAILURE(cb, -1, data);
	g_free(cbd);
}
Beispiel #9
0
static void isi_registration(struct ofono_call_forwarding *cf, int type,
                             int cls,
                             const struct ofono_phone_number *number,
                             int time, ofono_call_forwarding_set_cb_t cb,
                             void *data)
{
    struct forw_data *fd = ofono_call_forwarding_get_data(cf);
    struct isi_cb_data *cbd = isi_cb_data_new(cf, cb, data);
    int ss_code = forw_type_to_isi_code(type);

    char *ucs2 = NULL;

    size_t numlen = strlen(number->number);
    size_t sb_len = ALIGN4(6 + 2 * numlen);
    size_t pad_len = sb_len - (6 + 2 * numlen);

    uint8_t msg[7 + 6 + 28 * 2 + 3] = {
        SS_SERVICE_REQ,
        SS_REGISTRATION,
        SS_GSM_TELEPHONY,
        ss_code >> 8, ss_code & 0xFF,
        SS_SEND_ADDITIONAL_INFO,
        1,	/* Subblock count */
        SS_FORWARDING,
        sb_len,
        number->type,
        ss_code == SS_GSM_FORW_NO_REPLY ? time : SS_UNDEFINED_TIME,
        numlen,
        0,	/* Sub address length */
        /*
         * Followed by number in UCS-2 (no NULL termination),
         * zero sub address bytes, and 0 to 3 bytes of filler
         */
    };
    size_t msg_len = 7 + 6 + numlen * 2 + pad_len;

    if (cbd == NULL || fd == NULL || numlen > 28)
        goto error;

    DBG("forwarding type %d class %d number %s", type, cls, number->number);

    if (ss_code < 0)
        goto error;

    ucs2 = g_convert(number->number, numlen, "UCS-2BE", "UTF-8//TRANSLIT",
                     NULL, NULL, NULL);
    if (ucs2 == NULL)
        goto error;

    memcpy(msg + 13, ucs2, numlen * 2);
    g_free(ucs2);

    if (g_isi_client_send(fd->client, msg, msg_len, registration_resp_cb,
                          cbd, g_free))
        return;

error:
    CALLBACK_WITH_FAILURE(cb, data);
    g_free(cbd);
}

static void erasure_resp_cb(const GIsiMessage *msg, void *data)
{
    struct isi_cb_data *cbd = data;
    ofono_call_forwarding_set_cb_t cb = cbd->cb;
    GIsiSubBlockIter iter;
    uint8_t status;

    if (!check_resp(msg, SS_SERVICE_COMPLETED_RESP, SS_ERASURE))
        goto error;

    for (g_isi_sb_iter_init(&iter, msg, 6);
            g_isi_sb_iter_is_valid(&iter);
            g_isi_sb_iter_next(&iter)) {

        if (g_isi_sb_iter_get_id(&iter) != SS_GSM_FORWARDING_INFO)
            continue;

        if (!decode_gsm_forwarding_info(&iter, &status,	NULL, NULL,
                                        NULL))
            goto error;

        if (status & (SS_GSM_ACTIVE | SS_GSM_REGISTERED))
            goto error;

    }
    CALLBACK_WITH_SUCCESS(cb, cbd->data);
    return;

error:
    CALLBACK_WITH_FAILURE(cb, cbd->data);
}

static void isi_erasure(struct ofono_call_forwarding *cf, int type, int cls,
                        ofono_call_forwarding_set_cb_t cb, void *data)
{
    struct forw_data *fd = ofono_call_forwarding_get_data(cf);
    struct isi_cb_data *cbd = isi_cb_data_new(cf, cb, data);
    int ss_code = forw_type_to_isi_code(type);

    const uint8_t msg[] = {
        SS_SERVICE_REQ,
        SS_ERASURE,
        SS_GSM_TELEPHONY,
        ss_code >> 8, ss_code & 0xFF,
        SS_SEND_ADDITIONAL_INFO,
        0,		/* Subblock count */
    };

    DBG("forwarding type %d class %d", type, cls);

    if (cbd == NULL || fd == NULL || ss_code < 0)
        goto error;

    if (g_isi_client_send(fd->client, msg, sizeof(msg),
                          erasure_resp_cb, cbd, g_free))
        return;

error:
    CALLBACK_WITH_FAILURE(cb, data);
    g_free(cbd);
}

static void query_resp_cb(const GIsiMessage *msg, void *data)
{
    struct isi_cb_data *cbd = data;
    ofono_call_forwarding_query_cb_t cb = cbd->cb;
    GIsiSubBlockIter iter;

    struct ofono_call_forwarding_condition list = {
        .status = 0,
        .cls = 7,
        .time = 0,
        .phone_number = {
            .number[0] = '\0',
            .type = 0,
        },
    };
    uint8_t status;
    uint8_t ton;
    uint8_t noreply;
    char *number = NULL;

    if (!check_resp(msg, SS_SERVICE_COMPLETED_RESP, SS_INTERROGATION))
        goto error;

    for (g_isi_sb_iter_init(&iter, msg, 6);
            g_isi_sb_iter_is_valid(&iter);
            g_isi_sb_iter_next(&iter)) {

        DBG("Got %s", ss_subblock_name(g_isi_sb_iter_get_id(&iter)));

        if (g_isi_sb_iter_get_id(&iter) != SS_GSM_FORWARDING_INFO)
            continue;

        if (!decode_gsm_forwarding_info(&iter, &status, &ton, &noreply,
                                        &number))
            goto error;

        list.status = status & (SS_GSM_ACTIVE | SS_GSM_REGISTERED |
                                SS_GSM_PROVISIONED);
        list.time = noreply;
        list.phone_number.type = ton | 0x80;

        DBG("Number <%s>", number);

        strncpy(list.phone_number.number, number,
                OFONO_MAX_PHONE_NUMBER_LENGTH);
        list.phone_number.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
        g_free(number);

        DBG("forwarding query: %d, %d, %s(%d) - %d sec",
            list.status, list.cls, list.phone_number.number,
            list.phone_number.type, list.time);
    }
    CALLBACK_WITH_SUCCESS(cb, 1, &list, cbd->data);
    return;

error:
    CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data);
}


static void isi_query(struct ofono_call_forwarding *cf, int type, int cls,
                      ofono_call_forwarding_query_cb_t cb,
                      void *data)
{
    struct forw_data *fd = ofono_call_forwarding_get_data(cf);
    struct isi_cb_data *cbd = isi_cb_data_new(cf, cb, data);
    int ss_code = forw_type_to_isi_code(type);

    const uint8_t msg[] = {
        SS_SERVICE_REQ,
        SS_INTERROGATION,
        SS_GSM_TELEPHONY,
        ss_code >> 8, ss_code & 0xFF,
        SS_SEND_ADDITIONAL_INFO,
        0, /* Subblock count */
    };

    DBG("forwarding type %d class %d", type, cls);

    if (cbd == NULL || fd == NULL || cls != 7 || ss_code < 0)
        goto error;

    if (g_isi_client_send(fd->client, msg, sizeof(msg), query_resp_cb,
                          cbd, g_free))
        return;

error:
    CALLBACK_WITH_FAILURE(cb, 0, NULL, data);
    g_free(cbd);
}

static void reachable_cb(const GIsiMessage *msg, void *data)
{
    struct ofono_call_forwarding *cf = data;

    if (g_isi_msg_error(msg) < 0) {
        ofono_call_forwarding_remove(cf);
        return;
    }

    ISI_RESOURCE_DBG(msg);

    ofono_call_forwarding_register(cf);
}


static int isi_call_forwarding_probe(struct ofono_call_forwarding *cf,
                                     unsigned int vendor, void *user)
{
    GIsiModem *modem = user;
    struct forw_data *fd;

    fd = g_try_new0(struct forw_data, 1);
    if (fd == NULL)
        return -ENOMEM;

    fd->client = g_isi_client_create(modem, PN_SS);
    if (fd->client == NULL) {
        g_free(fd);
        return -ENOMEM;
    }

    ofono_call_forwarding_set_data(cf, fd);

    g_isi_client_verify(fd->client, reachable_cb, cf, NULL);

    return 0;
}