#include "selfcare_res.h" #include "utils_queue.h" #include "selfcare_udp.h" #include "selfcare_endecode.h" #include "log.h" extern selfcare_res_s *selfcare_assign_res(); extern void crm_delete_subscriber_profile(char *service_num, int account_type, int account_id); extern int crm_prov_handle_response(selfcare_res_s *res); extern ulong TransStrTimeToSecond(const char *str_time);//YYYY-MM-DD HH:MM:YY extern int dba_crm_get_product_rent(int from, int package_id); extern void _selfcare_udp_process(); /* 空闲资源队列*/ static queueADT g_res_queue; static int g_res[SELFCARE_RES_NUM]; /* 资源 */ selfcare_res_s g_res_arr[SELFCARE_RES_NUM]; static int g_res_run_flag; static int _selfcare_fsm_sendudp(selfcare_res_s *res) { int ret; /* 1. 解析selfcare系统发来的消息 */ _rest_msg_s msg; memset(&msg, 0x00, sizeof(msg)); ret = selfcare_decode(res->req,res->req_type, &msg); if(ret != SUCCESS) { LOG_E("[httpserv] decode failed\n"); return ret; } LOG_D("[httpserv] decode suc. res_id[%d]\n", res->id); /* 2. 编码 */ char buf[1024]; int len; msg.header.src_ref = res->id; len = encode_rest(&msg, (u8*)buf); if(msg.msg_type == REST_CRM_DELETE_SUBS_REQ) { crm_delete_subscriber_profile(msg.msg.delete_subs.msisdn, msg.msg.delete_subs.account_type, msg.msg.delete_subs.account_id); if(msg.msg.delete_subs.account_type != 1)//not mobile { //return OK to CRM here res->resp.msg_type = REST_CRM_DELETE_SUBS_RES; res->resp.msg.delete_subs_res.result = 0; res->resp.msg.delete_subs_res.error_code = 2001; res->state = SELFCARE_WAIT_SEND2SELFCARE_RESP; return SUCCESS; } } /* 3. 发送udp消息到 ocs */ if(len > 0) { ret = selfcare_udp_send(buf, len); LOG_D("[httpserv] send udp suc.res_id[%d] ret[%d]\n", res->id, ret); return SUCCESS; } LOG_E("[httpserv] err.send udp err. res_id[%d]\n", res->id); return FAILURE; } static int _selfcare_fsm_sendudp_local(selfcare_res_s *res, _rest_msg_s msg) { int ret; char buf[1024]; int len; msg.header.src_ref = res->id; len = encode_rest(&msg, (u8*)buf); /* 3. 发送udp消息到 ocs */ if(len > 0) { ret = selfcare_udp_send(buf, len); LOG_D("[httpserv] send udp suc.res_id[%d] ret[%d]\n", res->id, ret); return SUCCESS; } LOG_E("[httpserv] err.send udp err. res_id[%d]\n", res->id); return FAILURE; } /* 发送回复到selfcare系统 */ static void _selfcare_fsm_send2selfcare(const selfcare_res_s *res) { /* 编码 */ char *buf = NULL; selfcare_encode(res->req_type, &res->resp, &buf); /* 回复 */ selfcare_httpsrv_send(res->req, 200, buf); } void _selfcare_res_fsm(void) //static void _selfcare_res_fsm(void) { int i; selfcare_res_s *res; for(i = 1; i < SELFCARE_RES_NUM; ++i) { res = &g_res_arr[i]; res->timer++; switch(res->state) { case SELFCARE_IDLE: break; case SELFCARE_WAIT_SELFCARE_REQ: break; case SELFCARE_WAIT_SEND2OCS_REQ: LOG_D("[httpserv] res_id[%d] state[%s->%s]\n", res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_WAIT_OCS_RESP)); _selfcare_fsm_sendudp(res); res->state = SELFCARE_WAIT_OCS_RESP; res->timer = 0; break; case SELFCARE_WAIT_OCS_RESP: /* 3秒没有处理完就超时处理 */ if(res->timer >= 3000) { // send httpserv time out ??? LOG_D("[httpserv] res_id[%d] timeout state[%s->%s]\n", res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_RELEASE)); res->state = SELFCARE_RELEASE; } break; case SELFCARE_WAIT_SEND2SELFCARE_RESP: LOG_D("[httpserv] res_id[%d] state[%s->%s]\n", res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_RELEASE)); _selfcare_fsm_send2selfcare(res); res->state = SELFCARE_RELEASE; res->timer = 0; break; case SELFCARE_LOCAL_INIT_REQ: LOG_D("[httpserv] res_id[%d] state[%s->%s]\n", res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_WAIT_OCS_RESP)); res->state = SELFCARE_WAIT_OCS_RESP; res->timer = 0; // _selfcare_fsm_sendudp(res); break; case SELFCARE_LOCAL_INIT_RESP: LOG_D("[httpserv] res_id[%d] state[%s->%s]\n", res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_RELEASE)); crm_prov_handle_response(res); res->state = SELFCARE_RELEASE; res->timer = 0; break; case SELFCARE_RELEASE: case SELFCARE_STATE_MAX: default: memset(&g_res_arr[i], 0x00, sizeof(selfcare_res_s)); selfcare_res_release(i); LOG_D("[httpserv] release suc. res_id[%d] state[%s]\n", i, selfcare_res_stateprint(SELFCARE_IDLE)); break; } } } /*--------------------------------------------------------*/ int crm_prov_mobile_prepaid_account(char sub_data[][1024], int cug_id, int user_class) {//user class=1/2 local / tourist selfcare_res_s *res = selfcare_assign_res(); _rest_msg_s *msg=NULL, rest_msg; if(res == NULL) return 0; msg = &rest_msg; msg->msg_type = REST_CRM_CREATE_ACCT_REQ; strcpy(msg->msg.create_acct.msisdn, sub_data[3]); msg->msg.create_acct.customer_id = atoi(sub_data[6]); msg->msg.create_acct.account_id = atoi(sub_data[7]); msg->msg.create_acct.product_id = atoi(sub_data[8]); msg->msg.create_acct.plan_id = atoi(sub_data[14]); msg->msg.create_acct.user_class = user_class; msg->msg.create_acct.cug_id = cug_id;//atoi(sub_data[16]); msg->msg.create_acct.balance = atoi(sub_data[12]); msg->msg.create_acct.expiry_date = TransStrTimeToSecond(sub_data[13]); msg->msg.create_acct.birthday = TransStrTimeToSecond(sub_data[11]); msg->msg.create_acct.rent_charge = dba_crm_get_product_rent(0, msg->msg.create_acct.plan_id); res->local_init_db_key = atoi(sub_data[0]); res->local_init_flag = 1; res->local_init_oc = REST_CRM_CREATE_ACCT_REQ; _selfcare_fsm_sendudp_local(res, rest_msg); res->state = SELFCARE_LOCAL_INIT_REQ; return 1; } int crm_prov_handle_response(selfcare_res_s *res) { char sql[2048]; if(res == NULL) return 0; switch(res->local_init_oc) { case REST_CRM_CREATE_ACCT_REQ: if(res->resp.msg.create_acct_res.error_code == OCS_RES_SUCCEED) { sprintf(sql, "UPDATE tb_sync_mobile set STATE=2, OPER_RESULT=1 where PRE_ID=%d", res->local_init_db_key); } else { sprintf(sql, "UPDATE tb_sync_mobile set STATE=2, OPER_RESULT=2 where PRE_ID=%d", res->local_init_db_key); } //subs_provisioning_update_result(sql); break; default: break; } return 1; } /*--------------------------------------------------------*/ static void *_selfcare_res_thread(void *data) { prctl(PR_SET_NAME, "selfcare-fsm"); while(g_res_run_flag) { _selfcare_udp_process(); _selfcare_res_fsm(); usleep(1000); } pthread_exit(NULL); return NULL; } static int _selfcare_res_inittask() { pthread_t handle; g_res_run_flag = 1; if(pthread_create(&handle, NULL, _selfcare_res_thread, NULL)) { printf("Thread create err !!!\n"); return FAILURE; if ( pthread_detach(handle) ) { printf("Thread detached err !!!\n"); return FAILURE; } } return SUCCESS; } int selfcare_res_get(int *res_id) { queueElementT elem = QueueDelete(g_res_queue); if(elem == NULL) { LOG_E("[selfcare-res] get err. null\n"); return FAILURE; } *res_id = *(int*)elem; return SUCCESS; } int selfcare_res_release(const int res_id) { int ret; if(res_id>=SELFCARE_RES_NUM) return FAILURE; ret = QueueEnter(g_res_queue, &g_res[res_id]); if(ret != SUCCESS_QUEUE) { return FAILURE; } return SUCCESS; } const char *selfcare_res_stateprint(selfcare_state_e state) { switch(state) { case SELFCARE_IDLE: return "idle"; case SELFCARE_WAIT_SELFCARE_REQ: return "wait_selfcare_req"; case SELFCARE_WAIT_SEND2OCS_REQ: return "send2ocs_req"; case SELFCARE_WAIT_OCS_RESP: return "wait_ocs_resp"; case SELFCARE_WAIT_SEND2SELFCARE_RESP: return "wait_send2selfcare_resp"; case SELFCARE_LOCAL_INIT_REQ: return "local initiating process - send request"; case SELFCARE_LOCAL_INIT_RESP: return "local initiating process-wait for response"; case SELFCARE_RELEASE: return "release"; default: return "unknow"; } return "unknow"; } int selfcare_res_init(int argc, char **argv) { int ret; /* 初始化空闲资源队列*/ g_res_queue = QueueCreate(SELFCARE_RES_NUM); if(g_res_queue == NULL) { return FAILURE; } /* 加载空闲资源 */ int i = 0; for(i = 1; i < SELFCARE_RES_NUM; ++i) { g_res[i] = i; ret = QueueEnter(g_res_queue, &g_res[i]); if(ret != SUCCESS_QUEUE) { return FAILURE; } } _selfcare_res_inittask(); return SUCCESS; } void selfcare_res_uninit(void) { QueueDestroy(g_res_queue); g_res_run_flag = 0; }