/**
  * 对外发送短信接口
  * 参数
  * 
  * $tel 手机号码
  * $msg 信息内容,仅用于发送验证码,且只支持GBK编码
  * 
  * 返回值
  * json array 0 success ,-1 fail
  */
 public function send_sms($tel, $msg_type = 1)
 {
     return array('ret' => 0, '_log' => '发送成功');
     if (ENVIRONMENT == 'development') {
         return array('ret' => 0, '_log' => '发送成功');
     }
     @session_start();
     if (isset($_SESSION[self::SESSION_EXPIR_TIME_NAME]) and time() - $_SESSION[self::SESSION_EXPIR_TIME_NAME] < 60) {
         return array('ret' => -2, '_log' => '服务器繁忙,请稍后再试');
     }
     //get host
     $CI =& get_instance();
     $CI->config->load('setting');
     //建立TCP连接
     $client = new TP_NetClient_TCP();
     if (@$client->connect($CI->config->item('sms_host'), $CI->config->item('sms_port'), self::TIMEOUT)) {
         $pkg = $this->gen_msg($tel, $msg_type);
         $client->send($pkg);
         //发包
         $ret = json_decode(@$client->recv());
         //收包
         if ($ret && $ret->ret == 0) {
             return array('ret' => 0, '_log' => '');
         } else {
             return array('ret' => -1, '_log' => '短信发送失败');
         }
     }
 }
 /**
  * 调用后台接口
  * @param PBMessage $pb_obj
  * @param PBMessage $ret_obj
  * @return bool
  */
 public static function request(PBMessage $pb_obj, PBMessage $ret_obj, &$result_code = '', &$result_info = '', &$potalseq = '', &$card_info = array())
 {
     if (!isset($pb_obj->name)) {
         return FALSE;
     }
     // serialize
     $string = pack('a20nn', $pb_obj->name, 0, 1) . $pb_obj->SerializeToString();
     $pkg = pack('N', strlen($string)) . $string;
     if (empty(static::$dns_object) or !isset(static::$dns_object->ip) or !isset(static::$dns_object->port)) {
         static::log_buy_info("DNS解析出错");
         return FALSE;
     }
     //建立TCP连接
     $client = new TP_NetClient_TCP();
     if (@$client->connect(static::$dns_object->ip, static::$dns_object->port, self::PORTAL_TIMEOUT)) {
         $client->send($pkg);
         //发包
         $ret = @$client->recv();
         //收包
     } else {
         static::log_buy_info("建立TCP连接出错");
         return FALSE;
     }
     $arr = @unpack('Nlen/a20name/ncode/nver', substr($ret, 0, 28));
     if (!isset($arr) or $arr['len'] <= 0) {
         static::log_buy_info("解析回包错误");
         return FALSE;
     }
     $data = substr($ret, 28, $arr['len']);
     $ret_obj->parseFromString($data);
     $potalseq = $ret_obj->head()->PortalSeq();
     //如果请求为pay
     if ($pb_obj->head()->CmdCode() == 'PAY') {
         $a = $ret_obj->product();
         if (empty($a)) {
             static::log_buy_info("payans 中的product数据为空!\n ");
         } else {
             //$card_no = $ret_obj->product()->productparamlist('CardIdList');
             //$card_no = $ret_obj->product()->productparamlist(1)->value();
             for ($i = 0; $i < $ret_obj->product()->productparamlist_size(); $i++) {
                 $key = $ret_obj->product()->productparamlist($i)->key();
                 if ($key == 'CardIdList') {
                     $card_info['card_no'] = $ret_obj->product()->productparamlist($i)->value();
                     static::log_buy_info("card_no信息:" . $card_info['card_no']);
                     break;
                 }
             }
             $point = $ret_obj->product()->storagelistpoint();
             if ($ret_obj->product()->storageinfolist_size() > 0) {
                 $card_info['storage_type'] = $ret_obj->product()->storageinfolist($point)->storagetype();
                 static::log_buy_info("storagetype 信息:" . $card_info['storage_type']);
             }
         }
     }
     //请求失败
     if ($ret_obj->head()->CmdCode() != $pb_obj->head()->CmdCode() or $ret_obj->head()->ResultCode() != 0) {
         $result_code = $ret_obj->head()->ResultCode();
         $result_info = $ret_obj->head()->ResultInfo();
         //static::log_buy_info("\nResultCode:".$ret_obj->head()->ResultCode()."|Errorcode:".$ret_obj->head()->Errorcode()."|Errinfo:".$ret_obj->head()->Errinfo());
         //echo '<pre>', $ret_obj->head()->ResultCode(), "\n",  $ret_obj->head()->Errorcode(), "\n",  $ret_obj->head()->Errinfo();
         return FALSE;
     }
     return TRUE;
 }