void test2() { const char* hex = "0102"; uint8_t bytebuf[1024]; sgs_id* id; int result; size_t i; result = hextobytes(hex, bytebuf); if (result == -1) { printf("Error: invalid ID string (%s).\n", hex); return; } printf("hextobytes() returned %d\n", result); if ((id = sgs_id_create(bytebuf, strlen(hex)/2, NULL)) == NULL) { printf("Error: invalid ID string (%s).\n", hex); return; } printf("byte: { "); for (i=0; i < sgs_id_get_byte_len(id); i++) { if (i > 0) printf(", "); printf("%d", *(sgs_id_get_bytes(id) + i)); } printf(" }\n"); sgs_id_destroy(id); }
void test1() { uint8_t bytes[] = { 1, 2, 3 }; sgs_id* id; id = sgs_id_create(bytes, sizeof(bytes), NULL); if (id == NULL) { sgs_id_destroy(id); perror("init()"); } printf("bytelen = %ld\n", sgs_id_get_byte_len(id)); printf("memcmp = %d\n", memcmp(bytes, sgs_id_get_bytes(id), sgs_id_get_byte_len(id))); sgs_id_destroy(id); }
/* * sgs_session_impl_recv_msg() */ int sgs_session_impl_recv_msg(sgs_session_impl *session) { int8_t result; ssize_t namelen, offset, offset2; sgs_id* channel_id; sgs_id* sender_id; sgs_message msg; const uint8_t* msg_data; sgs_channel* channel; size_t msg_datalen; if (sgs_msg_deserialize(&msg, session->msg_buf, sizeof(session->msg_buf)) == -1) return -1; //sgs_msg_dump(&msg); msg_datalen = sgs_msg_get_datalen(&msg); msg_data = sgs_msg_get_data(&msg); if (sgs_msg_get_version(&msg) != SGS_MSG_VERSION) { errno = SGS_ERR_BAD_MSG_VERSION; return -1; } if (sgs_msg_get_service(&msg) == SGS_APPLICATION_SERVICE) { switch (sgs_msg_get_opcode(&msg)) { case SGS_OPCODE_LOGIN_SUCCESS: /** field 1: session-id (compact-id format) */ session->session_id = sgs_id_create(msg_data, msg_datalen, &offset); if (session->session_id == NULL) return -1; /** field 2: reconnection-key (compact-id format) */ session->reconnect_key = sgs_id_create(msg_data + offset, msg_datalen - offset, NULL); if (session->reconnect_key == NULL) return -1; if (session->connection->ctx->logged_in_cb != NULL) session->connection->ctx->logged_in_cb(session->connection, session); return 0; case SGS_OPCODE_LOGIN_FAILURE: /** field 1: error string (first 2 bytes = length of string) */ if (session->connection->ctx->login_failed_cb != NULL) session->connection->ctx->login_failed_cb(session->connection, msg_data + 2, read_len_header(msg_data)); return 0; case SGS_OPCODE_SESSION_MESSAGE: /** * field 1: sequence number (8 bytes) * TODO first 8 bytes are a sequence number that is currently * ignored */ offset = 8; /** field 2: message (first 2 bytes = length of message) */ if (session->connection->ctx->recv_message_cb != NULL) session->connection->ctx->recv_message_cb(session->connection, msg_data + offset + 2, read_len_header(msg_data + offset)); return 0; case SGS_OPCODE_RECONNECT_SUCCESS: if (session->connection->ctx->reconnected_cb != NULL) session->connection->ctx->reconnected_cb(session->connection); return 0; case SGS_OPCODE_RECONNECT_FAILURE: sgs_connection_impl_disconnect(session->connection); return 0; case SGS_OPCODE_LOGOUT_SUCCESS: session->connection->expecting_disconnect = 1; return 0; default: errno = SGS_ERR_BAD_MSG_OPCODE; return -1; } } else if (sgs_msg_get_service(&msg) == SGS_CHANNEL_SERVICE) { switch (sgs_msg_get_opcode(&msg)) { case SGS_OPCODE_CHANNEL_JOIN: /** field 1: channel name (first 2 bytes = length of string) */ namelen = read_len_header(msg_data); /** field 2: channel-id (compact-id format) */ channel_id = sgs_id_create(msg_data + namelen + 2, msg_datalen - namelen - 2, NULL); if (channel_id == NULL) return -1; if (sgs_map_contains(session->channels, channel_id)) { errno = SGS_ERR_ILLEGAL_STATE; sgs_id_destroy(channel_id); return -1; } channel = sgs_channel_impl_create(session, channel_id, (const char*)(msg_data + 2), namelen); if (channel == NULL) return -1; result = sgs_map_put(session->channels, channel_id, channel); if (result == -1) return -1; if (session->connection->ctx->channel_joined_cb != NULL) session->connection->ctx->channel_joined_cb(session->connection, channel); return 0; case SGS_OPCODE_CHANNEL_LEAVE: /** field 1: channel-id (compact-id format) */ channel_id = sgs_id_create(msg_data, msg_datalen, NULL); if (channel_id == NULL) return -1; channel = sgs_map_get(session->channels, channel_id); sgs_id_destroy(channel_id); if (channel == NULL) { errno = SGS_ERR_UNKNOWN_CHANNEL; return -1; } if (session->connection->ctx->channel_left_cb != NULL) session->connection->ctx->channel_left_cb(session->connection, channel); sgs_map_remove(session->channels, sgs_channel_impl_get_id(channel)); sgs_channel_impl_destroy(channel); return 0; case SGS_OPCODE_CHANNEL_MESSAGE: /** field 1: channel-id (compact-id format) */ channel_id = sgs_id_create(msg_data, msg_datalen, &offset); if (channel_id == NULL) return -1; channel = sgs_map_get(session->channels, channel_id); sgs_id_destroy(channel_id); /** * field 2: sequence number (8 bytes) * TODO next 8 bytes are a sequence number that is currently ignored */ offset += 8; /** field 3: session-id of sender (compact-id format) */ sender_id = sgs_id_create(msg_data + offset, msg_datalen - offset, &offset2); if (sender_id == NULL) return -1; offset += offset2; if (channel == NULL) { errno = SGS_ERR_UNKNOWN_CHANNEL; return -1; } if (session->connection->ctx->channel_recv_msg_cb != NULL) { sender_id = sgs_id_is_server(sender_id) ? NULL : sender_id; /** field 4: message (first 2 bytes = length of message) */ session->connection->ctx->channel_recv_msg_cb(session->connection, channel, sender_id, msg_data + offset + 2, read_len_header(msg_data + offset)); } sgs_id_destroy(sender_id); return 0; default: errno = SGS_ERR_BAD_MSG_OPCODE; return -1; } } else { errno = SGS_ERR_BAD_MSG_SERVICE; return -1; } }