阿里云IOT-SDK源码修改:可用于arm开发板,实现和阿里云相互发布和订阅的代码分析

#include "dev_sign_api.h"
#include "mqtt_api.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <cJSON.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
char DEMO_PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char DEMO_DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
//云端下发数据函数  
void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
	int fd;
	const char *leds = "/dev/dtsled";
	cJSON *json = NULL;
	cJSON *json_params = NULL;
	cJSON *json_id = NULL;
	cJSON *json_led = NULL;
    iotx_mqtt_topic_info_t     *topic_info = (iotx_mqtt_topic_info_pt) msg->msg;
    switch (msg->event_type) {
        case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
            EXAMPLE_TRACE("Topic  : %.*s", topic_info->topic_len, topic_info->ptopic);
            EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload);
            EXAMPLE_TRACE("\n");
		/*函数:cJSON_Parse,用于解析数据包
		使用该函数会通过malloc()函数在内存中开辟一个空间,使用完成需要手动释放,cJSON_Delete(json);
		*/
		json = cJSON_Parse(topic_info->payload);			
		if (!json)  
		{  
			HAL_Printf("Error before: [%s]\r\n",cJSON_GetErrorPtr());  
		} 
		else
		{
			json_id = cJSON_GetObjectItem(json , "id"); 
			if(json_id->type == cJSON_String)
			{
				HAL_Printf("id:%s\r\n", json_id->valuestring);  
			}
			json_params = cJSON_GetObjectItem(json , "params");  
			if(json_params)  
			{  
			/*cJSON_GetObjectItem()函数
			从cJSON结构体中查找某个子节点名称(键名称),如果查找成功可把该子节点序列化到cJSON结构体中。
			结构体的成员有:*/
			typedef struct cJSON {
       		struct cJSON*next,*prev;           	   /* 遍历数组或对象链的前向或后向链表指针*/
       		struct cJSON *child;                   /*数组或对象的孩子节点*/
       		int type;                              /* key的类型*/
       		char *valuestring;                     /*字符串值*/
       		int valueint;                          /* 整数值*/
       		double valuedouble;                    /* 浮点数值*/
       		char *string;                          /* key的名字*/
			} cJSON;
			*/
				if(cJSON_GetObjectItem(json_params, "led"))
				{
					json_led  = cJSON_GetObjectItem(json_params, "led");
					if(json_led->type == cJSON_Number)
					{
						HAL_Printf("LED:%d\r\n", json_led->valueint);  
						if((fd = open(leds, O_RDWR|O_NOCTTY|O_NDELAY))<0)		
							HAL_Printf("open %s failed\n",leds);   	
						else{			
							write(fd,&(json_led->valueint), 4);     			
							HAL_Printf("ioctl %s success, led %d\n",leds,json_led->valueint);		
						}	
						close(fd);
					}
				}
		}
		cJSON_Delete(json);
            break;
        default:
            break;
	}
}
//订阅指定的topic,即表示可以接收运平台上,哪些Topic的报文
int example_subscribe(void *handle)
{
    int res = 0;
	//需要订阅的主题   /thing/service/property/set:表示设备属性设置(用于云向客户端发送指令。eg:开灯,关灯),权限是订阅
    const char *fmt = "/sys/%s/%s/thing/service/property/set"	;
    char *topic = NULL;
    int topic_len = 0;
	topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
    topic = HAL_Malloc(topic_len);
    if (topic == NULL) {
        EXAMPLE_TRACE("memory not enough");
        return -1;
    }
    memset(topic, 0, topic_len);
    HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
	//订阅函数
    res = IOT_MQTT_Subscribe(handle, topic, IOTX_MQTT_QOS0, example_message_arrive, NULL);
    if (res < 0) {
        EXAMPLE_TRACE("subscribe failed");
        HAL_Free(topic);
        return -1;
    }
    HAL_Free(topic);
    return 0;
}
 
int example_publish(void *handle)
{
    int res 		= 0;
	unsigned short  temp 	= 0;
	unsigned short  humid 	= 0;
	/*需要发布的主题  thing/event/property/post:
	表示设备属性上报(eg:上传温湿度数据,以及开关等状态回复,用来确定设备是否可以正常使用),权限是发布*/
	const char *fmt 	= "/sys/%s/%s/thing/event/property/post";
    char  *topic 		= NULL;
    int      topic_len 	= 0;
    char  *payload 	= NULL;  
	int fd = 0;
	int len = 0;unsigned short  adc_val = 0;
	const char *adc = "/dev/AP3216C";
	unsigned short databuf[3];
		
	payload = HAL_Malloc(200);
	memset(payload, 0, 200);
	if((fd = open(adc, O_RDWR))>0)
	{    usleep(100000); /*这是读取开发板三合传感器的关键。如果不加这个休眠,读出的值是0.
	推测是因为三合传感器的初始化需要时间,如果马上读取,三合传感器的值还没有显示到设备节点。所以读出的是0*/
		if((read(fd,databuf, sizeof(databuf)))==0)
		{  //分别取出三合传感器的值
		    humid= databuf[0];
			temp = databuf[1]; 
			adc_val = databuf[2];
		} 
	}
	close(fd);
	//为了调试
	sprintf(payload,"{\"params\":{\"CurrentTemperature\":%d,\"RelativeHumidity\":%d,\"LightLuxValue\":%d},\"method\":\"thing.event.property.post\"}",temp, humid, adc_val);
	
    	topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
    	topic = HAL_Malloc(topic_len);
    	if (topic == NULL) {
        	EXAMPLE_TRACE("memory not enough");
        	return -1;
    	}
    	memset(topic, 0, topic_len);
    	HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
		//将三合传感器的值发送给服务器上指定的topic
    	res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, payload, strlen(payload));
    	if (res < 0) {
        	EXAMPLE_TRACE("publish failed, res = %d", res);
        	HAL_Free(topic);
        	return -1;
    	}
    HAL_Free(topic);
	HAL_Free(payload);
    return 0;
 }
//回调函数:对云下发的数据,进行处理,在这里,我们只是将接受到的数据显示
 void example_event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
    EXAMPLE_TRACE("msg->event_type : %d", msg->event_type);
}

int main(int argc, char *argv[])
{
    void                   *pclient = NULL;
    int                     res = 0;
    int                     loop_cnt = 0;
    iotx_mqtt_param_t       mqtt_params;
	//这三行就是我们之前在文件wrappers/os/ubuntu/HAL_OS_linux.c中修改的那部分信息,也就是三元组信息
    HAL_GetProductKey(DEMO_PRODUCT_KEY);
    HAL_GetDeviceName(DEMO_DEVICE_NAME);
    HAL_GetDeviceSecret(DEMO_DEVICE_SECRET);

    EXAMPLE_TRACE("mqtt example");

    /* Initialize MQTT parameter */
    memset(&mqtt_params, 0x0, sizeof(mqtt_params));
    /* mqtt_params.host = "something.iot-as-mqtt.cn-shanghai.aliyuncs.com"; */
    /* mqtt_params.port = 1883; */
    /* mqtt_params.request_timeout_ms = 2000; */
    /* mqtt_params.clean_session = 0; */
    /* MQTT_PARAMS.KEEPALIVE_INTERVAL_MS = 60000; */
    /* MQTT_PARAMS.WRITE_BUF_SIZE = 1024; */
    /* MQTT_PARAMS.READ_BUF_SIZE = 1024; */
	//指定回调函数
    mqtt_params.handle_event.h_fp = example_event_handle;
	//尝试建立与服务器的MQTT连接。参数mqtt_params是iotx_mqtt_param_t 类型的结构体,其成员的已经在上面进行赋值
    pclient = IOT_MQTT_Construct(&mqtt_params);
    if (NULL == pclient) {
        EXAMPLE_TRACE("MQTT construct failed");
        return -1;
    }
	//订阅指定的topic,即表示可以接收运平台上,哪些Topic的报文
    res = example_subscribe(pclient);
    if (res < 0) {
        IOT_MQTT_Destroy(&pclient);
        return -1;
    }
	HAL_Printf("\r\ncJSON Version: %s\r\n", cJSON_Version());
    while (1) {
        if (0 == loop_cnt % 20) {
		//上报数据到云端,即向指定topic推送消息
            example_publish(pclient);
        }
		//用于接收云端下发的消息, 并调用用户在 IOT_MQTT_Subscribe() 时指定的回调函数,用于对数据进行处理。
        IOT_MQTT_Yield(pclient, 200);
        loop_cnt += 1;
    }
    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

One Piece&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值