/* Conditions: 14 Exit points: 4 M = 14 - 4 + 2 = 12 Cyclomatic complexity 12 */ uint32_t control_should_handle_packet(Control_t* c, Packet_t* p) { PacketHeader_t* head; uint32_t errCode = 0; if (c == NULL || p == NULL) return CtrlError_NullArgument; if (c->CurrentPacket.Data != NULL) return CtrlError_Busy; if ((errCode = packet_get_header(p, &head))) return errCode; switch (head->Command) { default: case CtrlCommand_Bad: case CtrlCommand_None: errCode = CtrlError_No; break; case CtrlCommand_OpenSession: case CtrlCommand_NewSession: case CtrlCommand_RefreshSession: case CtrlCommand_CloseSession: case CtrlCommand_GetFileKey: case CtrlCommand_Cancel: case CtrlCommand_KeepAlive: errCode = CtrlError_Yes; break; } return errCode; }
/* Conditions: 12 Exit points: 4 M = 12 - 4 + 2 = 3 Cyclomatic complexity 10 */ uint32_t control_handle_packet(Control_t* c, Packet_t* p) { uint32_t errCode = 0; PacketHeader_t* head; if (c == NULL || p == NULL) return CtrlError_NullArgument; if ((errCode = control_should_handle_packet(c, p))) return errCode; if ((errCode = packet_get_header(p, &head))) return errCode; c->CurrentPacket.Data = p->Data; c->CurrentPacket.Length = p->Length; c->ResponsePacket.Data = NULL; c->ResponsePacket.Length = 0; switch (head->Command) { default: errCode = CtrlError_Fail; break; case CtrlCommand_NewSession: case CtrlCommand_OpenSession: errCode = control_start_session(c, p); break; case CtrlCommand_RefreshSession: errCode = control_refresh_session(c, p); break; case CtrlCommand_CloseSession: errCode = control_close_session(c, p); break; case CtrlCommand_GetFileKey: errCode = control_get_file_key(c, p); break; case CtrlCommand_Cancel: errCode = control_cancel_current_command(c, p); break; case CtrlCommand_KeepAlive: errCode = control_keep_alive(c, p); break; } return errCode; }
/* Conditions: 18 Exit points: 1 M = 18 - 1 + 2 = 19 Cyclomatic complexity 19 */ uint32_t fp_handle_packet(Packet_t* packet, Packet_t* response) { uint32_t id; uint32_t retVal = 0; PacketHeader_t* head = NULL; uint16_t len = 0; uint8_t* data = NULL; uint8_t digest[32] = {0}; if (packet_get_header(packet, &head)) { // Error } if (packet_get_data_length(packet, &len)) { // Error } if (packet_get_data(packet, &data)) { // Error } switch (head->Command) { default: // Error break; case CtrlCommand_OpenSession: case CtrlCommand_NewSession: { id = fp_session_start(); if (packet_create(response, head->Command, (uint8_t*)&id, sizeof(id))) { // Error } break; } case CtrlCommand_RefreshSession: { if (len >= 4) { id = *(uint32_t*)data; fp_session_refresh(id); id = 0x01; } else id = fp_error_id_invalid; if (packet_create(response, head->Command, (uint8_t*)&id, sizeof(id))) { // Error } break; } case CtrlCommand_CloseSession: { if (len >= 4) { id = *(uint32_t*)data; fp_session_close(id); } break; } case CtrlCommand_GetFileKey: { if (len >= 4) { id = *(uint32_t*)data; if ((retVal = fp_generate_file_key(id, digest)) < 20) { if (packet_create(response, head->Command, (uint8_t*)&digest, sizeof(digest))) { // Error } } else { // Error message if (packet_create(response, head->Command, (uint8_t*)&retVal, sizeof(retVal))) { // Error } } } else { id = fp_error_id_invalid; if (packet_create(response, head->Command, (uint8_t*)&id, sizeof(id))) { // Error } } // Session ID is in data section break; } } return 0; }
/* process the incoming packet from qq_pending */ static gboolean packet_process(PurpleConnection *gc, guint8 *buf, gint buf_len) { qq_data *qd; gint bytes, bytes_not_read; guint8 header_tag; guint16 source_tag; guint16 cmd; guint16 seq; /* May be ack_seq or send_seq, depends on cmd */ UID uid; guint8 header_ex_fixed[3]; /* 3 zeors */ guint8 room_cmd; guint32 room_id; UPDCLS update_class; guint32 ship32; int ret; qq_transaction *trans; g_return_val_if_fail(buf != NULL && buf_len > 0, TRUE); qd = (qq_data *) gc->proto_data; qd->net_stat.rcved++; if (qd->net_stat.rcved <= 0) memset(&(qd->net_stat), 0, sizeof(qd->net_stat)); /* Len, header and tail tag have been checked before */ bytes = 0; bytes += packet_get_header(&header_tag, &source_tag, &cmd, &seq, buf + bytes); if (qd->client_version == 2010) { bytes += packet_get_header_ex(&uid, header_ex_fixed, buf + bytes); } #if 1 purple_debug_info("QQ", "==> [%05d] %s 0x%04X, source tag 0x%04X len %d\n", seq, qq_get_cmd_desc(cmd), cmd, source_tag, buf_len); #endif /* this is the length of all the encrypted data (also remove tail tag) */ bytes_not_read = buf_len - bytes - 1; /* ack packet, we need to update send tranactions */ /* we do not check duplication for server ack */ trans = qq_trans_find_rcved(gc, cmd, seq); if (trans == NULL) { /* new server command */ if ( !qd->is_login ) { qq_trans_add_remain(gc, cmd, seq, buf + bytes, bytes_not_read); } else { qq_trans_add_server_cmd(gc, cmd, seq, buf + bytes, bytes_not_read); qq_proc_server_cmd(gc, cmd, seq, buf + bytes, bytes_not_read); } return TRUE; } if (qq_trans_is_dup(trans)) { qd->net_stat.rcved_dup++; purple_debug_info("QQ", "dup [%05d] %s, discard...\n", seq, qq_get_cmd_desc(cmd)); return TRUE; } update_class = qq_trans_get_class(trans); ship32 = qq_trans_get_ship(trans); if (update_class != 0 || ship32 != 0) { purple_debug_info("QQ", "Update class %d, ship32 %d\n", update_class, ship32); } switch (cmd) { case QQ_CMD_TOKEN: case QQ_CMD_GET_SERVER: case QQ_CMD_TOKEN_EX: case QQ_CMD_CHECK_PWD: case QQ_CMD_LOGIN: ret = qq_proc_login_cmds(gc, cmd, seq, buf + bytes, bytes_not_read, update_class, ship32); if (ret != QQ_LOGIN_REPLY_OK) { if (ret == QQ_LOGIN_REPLY_REDIRECT) { redirect_server(gc); } return FALSE; /* do nothing after this function and return now */ } break; case QQ_CMD_ROOM: room_cmd = qq_trans_get_room_cmd(trans); room_id = qq_trans_get_room_id(trans); qq_proc_room_cmds(gc, seq, room_cmd, room_id, buf + bytes, bytes_not_read, update_class, ship32); break; default: qq_proc_client_cmds(gc, cmd, seq, buf + bytes, bytes_not_read, update_class, ship32); break; } return TRUE; }