展讯6531平台socket

最近公司接到一个新项目,搞展讯6531E平台的天气预报,基本流程其实也简单,就是手机端发送一个请求到服务器,然后服务器把数据发送回来,手机端接收并且解析就可以了,由于之前没有做过展讯socket相关的东西,网上能搜索到的资源非常有限,所以在此做个总结,非常欢迎展友给我指出其中的错误以及纰漏。

功能基本流程如下:

1、激活PDP、拿到net_id

2、socket 通信

3、关闭socket

4、detach PDP

说明:这个流程有很大的局限性,因为手机端跟服务器端只有请求跟相应请求两个交互,再无其他交互,所以设计的很简单,但是socket的操作六层大致如此

1、激活PDP

//TEST cmnet 回调函数
LOCAL void HandlePDPTESTMsg(MMIPDP_CNF_INFO_T *msg_ptr)
{
        if(PNULL == msg_ptr)
           {
                return;
        }
        SCI_TRACE_LOW("[MMIMMS]:HandlePDPTESTMsg msg_id=%d",msg_ptr->msg_id);
        switch(msg_ptr->msg_id)
        {
        case MMIPDP_ACTIVE_CNF:
            if(msg_ptr->result != 0)
            {
                //记得把else里面重复激活PDP的定时器关闭
                taiodu_net_id = msg_ptr->nsapi;   //这个是net_id 知名socket使用的链路
                SCI_TRACE_LOW("+++++++HandlePDPTESTMsg,case MMIPDP_ACTIVE_CNF,taiodu_net_id :%ld",taiodu_net_id);        
                TEST_OpenSocket();   //建立sock,开始搞事
            }else
            {
                //这里再开一个定时器,继续调用openTESTNet,一直到这个回调接收到MMIPDP_ACTIVE_CNF,并且msg_ptr->result != 0
            }
            break;
            // MMK_PostMsg(MAIN_IDLE_WIN_ID, MSG_TEST_NETLINK_SUCCESS, PNULL,0); //发送网络激活成功 break;
        case MMIPDP_DEACTIVE_CNF:
                break;
        case MMIPDP_DEACTIVE_IND:
                SCI_TRACE_LOW("+++++++HandlePDPMsg: MMIPDP_DEACTIVE_IND");
                //MMK_PostMsg(MAIN_IDLE_WIN_ID, MSG_TEST_NETLINK_DISCONNECT, PNULL,0); //发送网络断开 break;
        default:
                break;
        }
        //SCI_FREE(msg_ptr);
}
//打开cmnet
BOOLEAN openTESTNet(void)
{
        MMIPDP_ACTIVE_INFO_T active_info = {0};
        char apn_ptr[10] = {0};//apn string
        BOOLEAN ret = FALSE;
        strcpy(apn_ptr,"cmnet");
        if (MMIPHONE_IsSimAvailable(0))//判断飞行模式
        {
                SCI_TRACE_LOW("openTESTNet");

                active_info.dual_sys = 0;

                //注意这个auth_type,6531E的代码需要更新过新的网络参数工具

                active_info.auth_type = 1;
                active_info.priority = 3;
                active_info.app_handler = MMI_MODULE_COMMON;
                active_info.handle_msg_callback = HandlePDPTESTMsg;
                active_info.apn_ptr = apn_ptr;
                active_info.ps_service_rat = MN_TD_PREFER;        
                MNGPRS_ReadStorageExtReqQosEx(active_info.dual_sys,MN_GPRS_STORAGE_ALL,BROWSER_E,&active_info.qos_info);                
                ret =MMIAPIPDP_Active(&active_info);
        }
        SCI_TRACE_LOW("openTESTNet :MMIAPIPDP_Active = %d!", ret);
        return ret;
}



 

2、socket通信

  新建线程处理socket时间

PUBLIC uint32 HxWeather_CreateTask(void)
{
    if (0 != s_weather_task_id)
    {
        //之前创建的task还没有关闭!
        return 0;
    }

    s_weather_task_id = SCI_CreateThread( 
                        "T_WEATHER", 
                        "Q_WEATHER", 
                        Weather_TaskHandle, 
                        0, 
                        0, 
                        WEATHER_STACK_SIZE, 
                        WEATHER_STACK_QUEUE_NUM, 
#ifdef WIN32
                        30,
#else
                        PRI_APP_WEATHER_TASK, 
#endif
                        SCI_PREEMPT, 
                        SCI_AUTO_START);
    
    SCI_TRACE_LOW(" HxWeather_CreateTask    create task ID %d", s_weather_task_id);
    return s_weather_task_id;
}

LOCAL void Weather_TaskHandle(uint32 argc, void * argv)
{
    xSignalHeaderRec                  *signal_ptr = PNULL;
    uint32                      sock_id = 0;
    static   BOOLEAN            is_on_free= FALSE;
    BLOCK_ID tsak_id = SCI_IdentifyThread();  // 获取当前taskID

    
 
    for(;;)
    {
        SCI_TRACE_LOW("Weather_TaskHandle Entry for(;;) !");
        
        signal_ptr = (xSignalHeaderRec *)SCI_GetSignal(tsak_id);

        SCI_TRACE_LOW("Weather_TaskHandle sci_sock_select sig_ptr->SignalCode = %d",signal_ptr->SignalCode);
        SCI_TRACE_LOW("Weather_TaskHandle sci_sock_select sig_ptr->SignalCode = %d",signal_ptr->SignalCode);
        SCI_TRACE_LOW("Weather_TaskHandle sci_sock_select sig_ptr->SignalCode = %d",signal_ptr->SignalCode);
        SCI_TRACE_LOW("Weather_TaskHandle sci_sock_select sig_ptr->SignalCode = %d",signal_ptr->SignalCode);
        if (PNULL != signal_ptr)
        {
            switch(signal_ptr->SignalCode)
            {
                case SOCKET_READ_EVENT_IND:    //
                    //可读
                   if(HxWeatherRecvData(s_cosket_id))
                    {
                        //解析数据
                        
                        //is_continue = FALSE;
                        //SCI_ThreadExit();
                    }else
                    {
                            //接收错误会返回到这里
                            HxWeatherUpdateSetErrorType(HX_WEATHER_UPDATE_ERROR_RECV_DATA);
                             //is_continue = FALSE;
                             //SCI_ThreadExit();
                    }
                    break;


                case SOCKET_CONNECTION_CLOSE_EVENT_IND:
                    //is_continue = FALSE;  //结束循环
                    SCI_TRACE_LOW("Weather_TaskHandle   exit sur thread task!");
                    s_weather_task_id = 0;
                    SCI_ThreadExit();
                    //关闭
                    break;

                case SOCKET_WRITE_EVENT_IND:
                    memset(G_Weather_Dta, 0, G_Data_Buffer);
                    SCI_TRACE_LOW("Weather_TaskHandle  memset G_Weather_Dta 0 !");
                    HxWeatherSendRequest(s_cosket_id);
                    //连接
                    break;

                    default :
                        break;
            } 
        }else
        {
                SCI_TRACE_LOW("Weather_TaskHandle  SCI_GetSignal  ptr is NULL!");
        }
#if 0
        if (!s_weather_task_id)
        {
            SCI_TRACE_LOW("Weather_TaskHandle   exit sur thread task for ");
            SCI_ThreadExit();
        }
#endif
    }

}

打开socket

LOCAL int HxWeather_OpenSocket(void)
{
    int32 socket_id = 0;
    int return_ret = 0;
    int error = 0;
    struct sci_sockaddr  addr;
    //struct sci_sockaddrext connect_add;
    struct sci_hostent  * hostent_date = PNULL;
    uint32 ip = 0;
    uint32 hostip = 0;
    int rept_connect = 0;
    //int32 host_ip = 0;
    char addr_buf[128] = {0};
    uint16 port = 10620;
    sci_fd_set writefds;
    BLOCK_ID tsak_id = s_weather_task_id;//为socket事件新建的线程,由他来检测socket的动态,如果使用主线程,会导致主线程阻塞,系统崩溃
    BOOLEAN is_continue = FALSE; 
    xSignalHeaderRec* sig_ptr = NULL;    //task signal

    //创建socket
    
    socket_id = sci_sock_socket(AF_INET, SOCK_STREAM, 0, s_weather_net_id);

    s_cosket_id =  socket_id;

    SCI_TRACE_LOW("HxWeather_OpenSocket socket_id = %d",socket_id);
    SCI_TRACE_LOW("HxWeather_OpenSocket socket_id = %d",socket_id);
    SCI_TRACE_LOW("HxWeather_OpenSocket s_weather_net_id = %d",s_weather_net_id);
    SCI_TRACE_LOW("HxWeather_OpenSocket s_weather_net_id = %d",s_weather_net_id);

    if(socket_id == TCPIP_SOCKET_INVALID)
   {
        HxWeatherUpdateSetErrorType(HX_WEATHER_UPDATE_ERROR_SOCKET_CREATE);
        return 0;
    }

//设置属性
    error = sci_sock_setsockopt(socket_id, SO_NBIO, PNULL);//设置socket 为非阻塞模式
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_setsockopt error = %d",error);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_setsockopt error = %d",error);
    if(-1 == error )//失败
    {
        error = sci_sock_errno(socket_id);

        SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_errno error = %x",error);
        SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_errno error = %x",error);
        HxWeatherUpdateSetErrorType(HX_WEATHER_UPDATE_ERROR_SOCKET_CREATE);
        sci_sock_socketclose(socket_id);
        return 0;
    }

#if 0
    error = sci_sock_setsockopt(socket_id, SS_ASYNC, NULL);

    if(-1 == return_ret)
    {
        error = sci_sock_errno(socket_id);
        sci_sock_socketclose(socket_id);
        return 0;
    }
#endif

    //绑定
    //return_ret = sci_parse_host((char *)g_hxweather_domain,&ip,0);
   // return_ret = sci_parse_host_ext((char *)g_hxweather_domain, &ip, 0, s_weather_net_id);
    hostent_date = sci_gethostbyname(g_hxweather_domain);
    //SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext ip = %x",ip);
    //SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext ip = %x",ip);
    //SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext return_ret = %d",return_ret);
    //SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext return_ret = %d",return_ret);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext hostent_date = %x",hostent_date);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext hostent_date = %x",hostent_date);
    //SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext IP = %s",*(hostent_date->h_addr_list));
    //SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext IP = %s",*(hostent_date->h_addr_list));
    
    if(NULL == hostent_date) //获取IP addr失败
    {
        HxWeatherUpdateSetErrorType(HX_WEATHER_UPDATE_ERROR_GET_HOSTNAME);
        sci_sock_socketclose(socket_id);
       return 0;
    }

    SCI_MEMCPY(&hostip, hostent_date->h_addr_list[0], 4);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext hostip = %d",hostip);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext hostip = %d",hostip);
    //ntohl(ip);
    ip = ntohl(hostip);

    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext ip = %x",ip);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext ip = %x",ip);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext return_ret = %d",return_ret);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext return_ret = %d",return_ret);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext hostent_date->h_addr_list = %s",hostent_date->h_addr_list[0]);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext hostent_date->h_addr_list = %s",hostent_date->h_addr_list[0]);
    
    addr.family = AF_INET;
    //addr.ip_addr = htonl(ip);
    addr.ip_addr = htonl(ip);
    addr.port = htons(port);
    //memset(addr.sa_data, 0, 8 * sizeof(char));
    SCI_MEMSET((void*)addr.sa_data, 0, 8*sizeof(char));
    //sci_sock_bind(socket_id, &addr, sizeof(struct sci_sockaddr));

    //连接
    //非阻塞方式需要等待连接成功
    return_ret = sci_sock_connect(socket_id, &addr, sizeof(struct sci_sockaddr));
    if(-1 == return_ret)
    {
        for(rept_connect = 0; rept_connect < HXWEATHER_REPT_CONNECT_NUMBER; rept_connect ++)
        {
            //取得错误的原因
            error = sci_sock_errno(socket_id);
            if(error != EINPROGRESS)   //不是这个错误号的都需要关闭socket,属于严重的错误
            {
                HxWeatherUpdateSetErrorType(HX_WEATHER_UPDATE_ERROR_SOCK_CONNECT);
                sci_sock_socketclose(socket_id);
                return 0;
            }
            SCI_SLEEP(HXWEATHER_REPT_CONNECT_TIME);   // 1S一次重连
            return_ret = sci_sock_connect(socket_id, &addr, sizeof(struct sci_sockaddr));
            if(0 == return_ret)   // 重连成功,跳出循环 
            {
                 break;
            }
        }
        //获取错误的原因
        //error = sci_sock_errno(socket_id);
        SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_connect eror_num = %d",error);
    }
    
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_connect return_ret = %d",return_ret);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_connect return_ret = %d",return_ret);
     SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext addr.ip_addr = %x",addr.ip_addr);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_parse_host_ext addr.ip_addr = %x",addr.ip_addr);

    //监听
    //socket = s_mr_sockets[param].s;
    SCI_FD_ZERO (&writefds);
    SCI_FD_SET((long)socket_id, &writefds);
    //sci_sock_select(sci_fd_set * in, sci_fd_set * out, sci_fd_set * ex, long tv)
    return_ret = sci_sock_select(NULL, &writefds, NULL, 0); 
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_select return_ret = %d",return_ret);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_select return_ret = %d",return_ret);

    //注册event消息
    SCI_TRACE_LOW("HxWeather_OpenSocket  sci_sock_asyncselect task ID:%d", s_weather_task_id);
    return_ret = sci_sock_asyncselect(socket_id, s_weather_task_id, AS_CONNECT|AS_READ|AS_WRITE|AS_CLOSE);
     SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_select sci_sock_asyncselect = %d",return_ret);
    SCI_TRACE_LOW("HxWeather_OpenSocket sci_sock_select sci_sock_asyncselect = %d",return_ret);
    if(return_ret == -1)
    {
        sci_sock_errno(socket_id);
    }

    is_continue = TRUE;
    

    //前面connect连接成功,表明可以发送数据了....
    HxWeatherSendRequest(socket_id);   //有可能发送过程中,buf不足,发送失败,在下面的task里等待WRITE消息,继续发送

    //MMIAPIPDP_Deactive(MMI_MODULE_HXWEATHER);
    //sci_sock_connect(TCPIP_SOCKET_T so, struct sci_sockaddrext * addr_ptr, int addr_len)
    return socket_id;
}
发布了22 篇原创文章 · 获赞 9 · 访问量 8837

猜你喜欢

转载自blog.csdn.net/ljm_c_bok/article/details/78764305