isimodem: Refactor gprs-context driver

Use stack allocation for padding, and simplify message sending and
failure handling.
This commit is contained in:
Aki Niemi 2011-02-18 16:13:06 +02:00
parent 2141228651
commit 5c84a23515
1 changed files with 43 additions and 53 deletions

View File

@ -347,50 +347,44 @@ static void send_context_authenticate(GIsiClient *client, void *opaque)
struct context_data *cd = opaque; struct context_data *cd = opaque;
size_t username_len = strlen(cd->username); size_t username_len = strlen(cd->username);
size_t password_len = strlen(cd->password); size_t password_len = strlen(cd->password);
size_t sb_user_info_len = (3 + username_len + 3) & ~3;
size_t fill_sb_user_info_count =
sb_user_info_len - (3 + username_len);
uint8_t *fill_sb_user_info_data =
g_try_malloc0(fill_sb_user_info_count);
size_t sb_password_info_len = (3 + password_len + 3) & ~3;
size_t fill_sb_password_info_count =
sb_user_info_len - (3 + password_len);
uint8_t *fill_sb_password_info_data =
g_try_malloc0(fill_sb_password_info_count);
const unsigned char top[] = { /* Pad the fields to the next 32bit boundary */
size_t sb_userinfo_len = (3 + username_len + 3) & ~3;
uint8_t userinfo_pad[sb_userinfo_len - (3 + username_len)];
size_t sb_password_info_len = (3 + password_len + 3) & ~3;
uint8_t password_pad[sb_password_info_len - (3 + password_len)];
const uint8_t top[] = {
GPDS_CONTEXT_AUTH_REQ, GPDS_CONTEXT_AUTH_REQ,
cd->handle, cd->handle,
2, /* sub blocks */ 2, /* sub blocks */
GPDS_USER_NAME_INFO, GPDS_USER_NAME_INFO,
sb_user_info_len, sb_userinfo_len,
username_len, username_len,
/* Username goes here */ /* Username goes here */
/* Possible padding goes here */
}; };
const unsigned char bottom[] = { const uint8_t bottom[] = {
GPDS_PASSWORD_INFO, GPDS_PASSWORD_INFO,
sb_password_info_len, sb_password_info_len,
password_len, password_len,
/* Password goes here */ /* Password goes here */
/* Possible padding goes here */
}; };
const struct iovec iov[6] = { const struct iovec iov[6] = {
{ (uint8_t *)top, sizeof(top) }, { (uint8_t *)top, sizeof(top) },
{ cd->username, username_len }, { cd->username, username_len },
{ fill_sb_user_info_data, fill_sb_user_info_count }, { userinfo_pad, sizeof(userinfo_pad) },
{ (uint8_t *)bottom, sizeof(bottom) }, { (uint8_t *)bottom, sizeof(bottom) },
{ cd->password, password_len }, { cd->password, password_len },
{ fill_sb_password_info_data, fill_sb_password_info_count}, { password_pad, sizeof(password_pad) },
}; };
if (fill_sb_user_info_data == NULL memset(userinfo_pad, 0, sizeof(userinfo_pad));
&& fill_sb_user_info_count > 0) memset(password_pad, 0, sizeof(password_pad));
gprs_up_fail(cd);
if (fill_sb_password_info_data == NULL
&& fill_sb_password_info_count > 0)
gprs_up_fail(cd);
if (!g_isi_client_vsend(client, iov, 6, context_auth_cb, cd, NULL)) if (!g_isi_client_vsend(client, iov, 6, context_auth_cb, cd, NULL))
gprs_up_fail(cd); gprs_up_fail(cd);
@ -414,42 +408,38 @@ static void link_conf_cb(const GIsiMessage *msg, void *opaque)
struct context_data *cd = opaque; struct context_data *cd = opaque;
size_t apn_len = strlen(cd->apn); size_t apn_len = strlen(cd->apn);
size_t sb_apn_info_len = (3 + apn_len + 3) & ~3; size_t sb_apn_info_len = (3 + apn_len + 3) & ~3;
size_t fill_count = sb_apn_info_len - (3 + apn_len); size_t apn_pad[sb_apn_info_len - (3 + apn_len)];
uint8_t *fill_data = g_try_malloc0(fill_count);
if (fill_data == NULL && fill_count > 0) const uint8_t req[] = {
return gprs_up_fail(cd); GPDS_CONTEXT_CONFIGURE_REQ,
cd->handle, /* context ID */
cd->type, /* PDP type */
GPDS_CONT_TYPE_NORMAL,
cd->handle, /* primary context ID */
0x00, /* filler */
2, /* sub blocks */
GPDS_DNS_ADDRESS_REQ_INFO,
4, /* subblock length */
0, 0, /* padding */
GPDS_APN_INFO,
sb_apn_info_len,
apn_len,
/* Possible padding goes here */
};
if (check_resp(msg, GPDS_LL_CONFIGURE_RESP, 2, cd, gprs_up_fail)) { const struct iovec iov[3] = {
{ (uint8_t *)req, sizeof(req) },
{ cd->apn, apn_len },
{ apn_pad, sizeof(apn_pad) },
};
const unsigned char msg[] = { memset(apn_pad, 0, sizeof(apn_pad));
GPDS_CONTEXT_CONFIGURE_REQ,
cd->handle, /* context ID */
cd->type, /* PDP type */
GPDS_CONT_TYPE_NORMAL,
cd->handle, /* primary context ID */
0x00, /* filler */
2, /* sub blocks */
GPDS_DNS_ADDRESS_REQ_INFO,
4, /* subblock length */
0, 0, /* padding */
GPDS_APN_INFO,
sb_apn_info_len,
apn_len,
};
const struct iovec iov[3] = { if (!check_resp(msg, GPDS_LL_CONFIGURE_RESP, 2, cd, gprs_up_fail))
{ (uint8_t *)msg, sizeof(msg) }, return;
{ cd->apn, apn_len },
{ fill_data, fill_count}
};
if (!g_isi_client_vsend_with_timeout(cd->client, iov, 3,
GPDS_TIMEOUT, context_conf_cb, cd, NULL))
return gprs_up_fail(cd);
} else
return gprs_up_fail(cd);
if (!g_isi_client_vsend(cd->client, iov, 3, context_conf_cb, cd, NULL))
gprs_up_fail(cd);
} }
static void create_context_cb(const GIsiMessage *msg, void *opaque) static void create_context_cb(const GIsiMessage *msg, void *opaque)