*
*/
-#include "aim.h"
+#include <faim/aim.h>
/*
* aim_bos_setidle()
* time.
*
*/
-u_long aim_bos_setidle(struct aim_conn_t *conn, u_long idletime)
+u_long aim_bos_setidle(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ u_long idletime)
{
- return aim_genericreq_l(conn, 0x0001, 0x0011, &idletime);
+ return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime);
}
*
*
*/
-u_long aim_bos_changevisibility(struct aim_conn_t *conn, int changetype, char *denylist)
+u_long aim_bos_changevisibility(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ int changetype, char *denylist)
{
struct command_tx_struct newpacket;
u_short subtype;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
newpacket.type = 0x02;
newpacket.lock = 0;
- aim_tx_enqueue(&newpacket);
+ aim_tx_enqueue(sess, &newpacket);
- return (aim_snac_nextid); /* dont increment */
+ return (sess->snac_nextid); /* dont increment */
}
* TODO: Clean this up.
*
*/
-u_long aim_bos_setbuddylist(struct aim_conn_t *conn, char *buddy_list)
+u_long aim_bos_setbuddylist(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ char *buddy_list)
{
int i, j;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
newpacket.commandlen = packet_login_phase3c_hi_b_len - 6;
newpacket.lock = 1;
newpacket.data = (char *) malloc(newpacket.commandlen);
- aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, aim_snac_nextid);
+ aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, sess->snac_nextid);
j = 10; /* the next byte */
newpacket.lock = 0;
- aim_tx_enqueue(&newpacket);
+ aim_tx_enqueue(sess, &newpacket);
- return (aim_snac_nextid++);
+ return (sess->snac_nextid++);
}
/*
*
* Gives BOS your profile.
*
+ *
+ * The large data chunk given here is of unknown decoding.
+ * What I do know is that each 0x20 byte repetition
+ * represents a capability. People with only the
+ * first two reptitions can support normal messaging
+ * and chat (client version 2.0 or 3.0). People with
+ * the third as well can also support voice chat (client
+ * version 3.5 or higher). IOW, if we don't send this,
+ * we won't get chat invitations (get "software doesn't
+ * support chat" error).
+ *
+ * This data is broadcast along with your oncoming
+ * buddy command to everyone who has you on their
+ * buddy list, as a type 0x0002 TLV.
+ *
*/
-u_long aim_bos_setprofile(struct aim_conn_t *conn, char *profile)
+u_long aim_bos_setprofile(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ char *profile,
+ char *awaymsg)
{
- int packet_profile_len = 0;
struct command_tx_struct newpacket;
int i = 0;
-
- /* len: SNAC */
- packet_profile_len = 10;
- /* len: T+L (where t(0001)) */
- packet_profile_len += 2 + 2;
- /* len: V (where t(0001)) */
- packet_profile_len += strlen("text/x-aolrtf");
- /* len: T+L (where t(0002)) */
- packet_profile_len += 2 + 2;
- /* len: V (where t(0002)) */
- packet_profile_len += strlen(profile);
+ u_char funkydata[] = {
+ 0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+ 0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+
+ 0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+ 0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+
+ 0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+ 0x09, 0x46, 0x13, 0x43, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00
+ };
newpacket.type = 0x02;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
- newpacket.commandlen = packet_profile_len;
- newpacket.data = (char *) malloc(packet_profile_len);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
- i = 0;
+ newpacket.commandlen = 1152+strlen(profile)+1; /*arbitrarily large */
+ if (awaymsg)
+ newpacket.commandlen += strlen(awaymsg);
+
+ newpacket.data = (char *) malloc(newpacket.commandlen);
- i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, aim_snac_nextid);
-
- /* TLV t(0001) */
- newpacket.data[i++] = 0x00;
- newpacket.data[i++] = 0x01;
- /* TLV l(000d) */
- newpacket.data[i++] = 0x00;
- newpacket.data[i++] = 0x0d;
- /* TLV v(text/x-aolrtf) */
- memcpy(&(newpacket.data[i]), "text/x-aolrtf", 0x000d);
- i += 0x000d;
+ i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, sess->snac_nextid);
+ i += aim_puttlv_str(newpacket.data+i, 0x0001, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
+ i += aim_puttlv_str(newpacket.data+i, 0x0002, strlen(profile), profile);
+ /* why do we send this twice? */
+ i += aim_puttlv_str(newpacket.data+i, 0x0003, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
- /* TLV t(0002) */
- newpacket.data[i++] = 0x00;
- newpacket.data[i++] = 0x02;
- /* TLV l() */
- newpacket.data[i++] = (strlen(profile) >> 8) & 0xFF;
- newpacket.data[i++] = (strlen(profile) & 0xFF);
- /* TLV v(profile) */
- memcpy(&(newpacket.data[i]), profile, strlen(profile));
-
- aim_tx_enqueue(&newpacket);
+ /* Away message -- we send this no matter what, even if its blank */
+ if (awaymsg)
+ i += aim_puttlv_str(newpacket.data+i, 0x0004, strlen(awaymsg), awaymsg);
+ else
+ i += aim_puttlv_str(newpacket.data+i, 0x0004, 0x0000, NULL);
+
+ /* Capability information. */
+ i += aim_puttlv_str(newpacket.data+i, 0x0005, 0x0060, funkydata);
+
+ newpacket.commandlen = i;
+ aim_tx_enqueue(sess, &newpacket);
- return (aim_snac_nextid++);
+ return (sess->snac_nextid++);
}
/*
* Set group permisson mask. Normally 0x1f.
*
*/
-u_long aim_bos_setgroupperm(struct aim_conn_t *conn, u_long mask)
+u_long aim_bos_setgroupperm(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ u_long mask)
{
- return aim_genericreq_l(conn, 0x0009, 0x0004, &mask);
+ return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask);
}
/*
* TODO: Dynamisize.
*
*/
-u_long aim_bos_clientready(struct aim_conn_t *conn)
+u_long aim_bos_clientready(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
u_char command_2[] = {
/* placeholders for dynamic data */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff,
/* real data */
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01,
- 0x00, 0x13, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x01,
+ 0x00, 0x03,
+ 0x00, 0x04,
+ 0x06, 0x86,
+ 0x00, 0x02,
+ 0x00, 0x01,
+ 0x00, 0x04,
+ 0x00, 0x01,
+
+ 0x00, 0x03,
+ 0x00, 0x01,
+ 0x00, 0x04,
+ 0x00, 0x01,
+ 0x00, 0x04,
+ 0x00, 0x01,
+ 0x00, 0x04,
+ 0x00, 0x01,
+
+ 0x00, 0x06,
+ 0x00, 0x01,
+ 0x00, 0x04,
+ 0x00, 0x01,
+ 0x00, 0x08,
+ 0x00, 0x01,
+ 0x00, 0x04,
+ 0x00, 0x01,
+
+ 0x00, 0x09,
+ 0x00, 0x01,
+ 0x00, 0x04,
+ 0x00, 0x01,
+ 0x00, 0x0a,
+ 0x00, 0x01,
+ 0x00, 0x04,
+ 0x00, 0x01,
+
+ 0x00, 0x0b,
+ 0x00, 0x01,
+ 0x00, 0x04,
0x00, 0x01
};
int command_2_len = 0x52;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
newpacket.type = 0x02;
newpacket.commandlen = command_2_len;
newpacket.data = (char *) malloc (newpacket.commandlen);
memcpy(newpacket.data, command_2, newpacket.commandlen);
/* This write over the dynamic parts of the byte block */
- aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, aim_snac_nextid);
+ aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
- aim_tx_enqueue(&newpacket);
+ aim_tx_enqueue(sess, &newpacket);
- return (aim_snac_nextid++);
+ return (sess->snac_nextid++);
}
/*
* TODO: Move to aim_conn.
* TODO: Move to SNAC interface.
*/
-u_long aim_bos_reqrate(struct aim_conn_t *conn)
+u_long aim_bos_reqrate(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
- return aim_genericreq_n(conn, 0x0001, 0x0006);
+ return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
}
/*
* Rate Information Response Acknowledge.
*
*/
-u_long aim_bos_ackrateresp(struct aim_conn_t *conn)
+u_long aim_bos_ackrateresp(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
struct command_tx_struct newpacket;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
newpacket.type = 0x02;
newpacket.commandlen = 18;
+ if (conn->type != AIM_CONN_TYPE_BOS)
+ newpacket.commandlen += 2;
newpacket.data = (char *) malloc(newpacket.commandlen);
- aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, aim_snac_nextid);
+ aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, sess->snac_nextid);
newpacket.data[10] = 0x00;
newpacket.data[11] = 0x01;
newpacket.data[15] = 0x03;
newpacket.data[16] = 0x00;
newpacket.data[17] = 0x04;
+ if (conn->type != AIM_CONN_TYPE_BOS)
+ {
+ newpacket.data[16] = 0x00;
+ newpacket.data[17] = 0x05;
+ }
- aim_tx_enqueue(&newpacket);
+ aim_tx_enqueue(sess, &newpacket);
- return (aim_snac_nextid++);
+ return (sess->snac_nextid++);
}
/*
*
*
*/
-u_long aim_bos_setprivacyflags(struct aim_conn_t *conn, u_long flags)
+u_long aim_bos_setprivacyflags(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ u_long flags)
{
- return aim_genericreq_l(conn, 0x0001, 0x0014, &flags);
+ return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
}
/*
* because aparently it uses SNAC flags.
*
*/
-u_long aim_bos_reqpersonalinfo(struct aim_conn_t *conn)
+u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
struct command_tx_struct newpacket;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
newpacket.type = 0x02;
newpacket.commandlen = 12;
newpacket.data = (char *) malloc(newpacket.commandlen);
- aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, aim_snac_nextid);
+ aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid);
newpacket.data[10] = 0x0d;
newpacket.data[11] = 0xda;
- aim_tx_enqueue(&newpacket);
+ newpacket.lock = 0;
+ aim_tx_enqueue(sess, &newpacket);
- return (aim_snac_nextid++);
+ return (sess->snac_nextid++);
}
+u_long aim_setversions(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
+{
+ struct command_tx_struct newpacket;
+ int i;
+
+ newpacket.lock = 1;
+ if (conn)
+ newpacket.conn = conn;
+ else
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
+ newpacket.type = 0x02;
+ newpacket.commandlen = 10 + (4*11);
+
+ newpacket.data = (char *) malloc(newpacket.commandlen);
+ i = aim_putsnac(newpacket.data, 0x0001, 0x0017, 0x0000, sess->snac_nextid);
+
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+ i += aimutil_put16(newpacket.data+i, 0x0003);
+
+ i += aimutil_put16(newpacket.data+i, 0x0002);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+ i += aimutil_put16(newpacket.data+i, 0x0003);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+ i += aimutil_put16(newpacket.data+i, 0x0004);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+ i += aimutil_put16(newpacket.data+i, 0x0006);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+ i += aimutil_put16(newpacket.data+i, 0x0008);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+ i += aimutil_put16(newpacket.data+i, 0x0009);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+ i += aimutil_put16(newpacket.data+i, 0x000a);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+ i += aimutil_put16(newpacket.data+i, 0x000b);
+ i += aimutil_put16(newpacket.data+i, 0x0002);
+
+ i += aimutil_put16(newpacket.data+i, 0x000c);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+ i += aimutil_put16(newpacket.data+i, 0x0015);
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+
+#if 0
+ for (j = 0; j < 0x10; j++)
+ {
+ i += aimutil_put16(newpacket.data+i, j); /* family */
+ i += aimutil_put16(newpacket.data+i, 0x0003); /* version */
+ }
+#endif
+ newpacket.lock = 0;
+ aim_tx_enqueue(sess, &newpacket);
+
+ return (sess->snac_nextid++);
+}
+
+
/*
* aim_bos_reqservice(serviceid)
*
* Service request.
*
*/
-u_long aim_bos_reqservice(struct aim_conn_t *conn, u_short serviceid)
+u_long aim_bos_reqservice(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ u_short serviceid)
{
- return aim_genericreq_s(conn, 0x0001, 0x0004, &serviceid);
+ return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
}
/*
* Request BOS rights.
*
*/
-u_long aim_bos_reqrights(struct aim_conn_t *conn)
+u_long aim_bos_reqrights(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
- return aim_genericreq_n(conn, 0x0009, 0x0002);
+ return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
}
/*
* Request Buddy List rights.
*
*/
-u_long aim_bos_reqbuddyrights(struct aim_conn_t *conn)
+u_long aim_bos_reqbuddyrights(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
- return aim_genericreq_n(conn, 0x0003, 0x0002);
+ return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
}
/*
* back to the single. I don't see any advantage to doing it either way.
*
*/
-u_long aim_genericreq_n(struct aim_conn_t *conn, u_short family, u_short subtype)
+u_long aim_genericreq_n(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ u_short family, u_short subtype)
{
struct command_tx_struct newpacket;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
newpacket.type = 0x02;
newpacket.commandlen = 10;
newpacket.data = (char *) malloc(newpacket.commandlen);
memset(newpacket.data, 0x00, newpacket.commandlen);
- aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
+ aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
- aim_tx_enqueue(&newpacket);
- return (aim_snac_nextid++);
+ aim_tx_enqueue(sess, &newpacket);
+ return (sess->snac_nextid++);
}
/*
*
*
*/
-u_long aim_genericreq_l(struct aim_conn_t *conn, u_short family, u_short subtype, u_long *longdata)
+u_long aim_genericreq_l(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ u_short family, u_short subtype, u_long *longdata)
{
struct command_tx_struct newpacket;
u_long newlong;
/* If we don't have data, there's no reason to use this function */
if (!longdata)
- return aim_genericreq_n(conn, family, subtype);
+ return aim_genericreq_n(sess, conn, family, subtype);
newpacket.lock = 1;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
+
newpacket.type = 0x02;
newpacket.commandlen = 10+sizeof(u_long);
newpacket.data = (char *) malloc(newpacket.commandlen);
memset(newpacket.data, 0x00, newpacket.commandlen);
- aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
+ aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
/* copy in data */
newlong = htonl(*longdata);
memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long));
- aim_tx_enqueue(&newpacket);
- return (aim_snac_nextid++);
+ aim_tx_enqueue(sess, &newpacket);
+ return (sess->snac_nextid++);
}
-u_long aim_genericreq_s(struct aim_conn_t *conn, u_short family, u_short subtype, u_short *shortdata)
+u_long aim_genericreq_s(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ u_short family, u_short subtype, u_short *shortdata)
{
struct command_tx_struct newpacket;
u_short newshort;
/* If we don't have data, there's no reason to use this function */
if (!shortdata)
- return aim_genericreq_n(conn, family, subtype);
+ return aim_genericreq_n(sess, conn, family, subtype);
newpacket.lock = 1;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
+
newpacket.type = 0x02;
newpacket.commandlen = 10+sizeof(u_short);
newpacket.data = (char *) malloc(newpacket.commandlen);
memset(newpacket.data, 0x00, newpacket.commandlen);
- aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
+ aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
/* copy in data */
newshort = htons(*shortdata);
memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short));
- aim_tx_enqueue(&newpacket);
- return (aim_snac_nextid++);
+ aim_tx_enqueue(sess, &newpacket);
+ return (sess->snac_nextid++);
}
/*
* Request Location services rights.
*
*/
-u_long aim_bos_reqlocaterights(struct aim_conn_t *conn)
+u_long aim_bos_reqlocaterights(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
- return aim_genericreq_n(conn, 0x0002, 0x0002);
+ return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
}
/*
* Request ICBM parameter information.
*
*/
-u_long aim_bos_reqicbmparaminfo(struct aim_conn_t *conn)
+u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
- return aim_genericreq_n(conn, 0x0004, 0x0004);
+ return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
}