123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709 |
-
- #include "AirProtocol.hpp"
- #include <cmn/proto/params.h>
- #include <cmn/proto/ui/option_list.h>
- #include <megopp/util/scope_cleanup.h>
- #include <cmn/plugin_framework/plugin.h>
- #include <Cmnpp/Proto/Operate.h>
- #include <Cmnpp/Proto/Point.h>
- #include "cmn/proto/log.h"
- #include <Cmnpp/Link.h>
- #include "DataHelper.hpp"
- void AirProtocol::parameters_get(cmnproto_params* _param)
- {
- cmnproto_params_set(
- _param,
- u8"HISENSEAIRV301",
- CMNPROTO_VER,
- COMM_MAKE_VER_NUM(0, 0, 1),
- cmnenum_duplex_half, // 半双工驱动方式
- cmnenum_data_process_collect, // 该协议是采集协议
- cmnenum_linkmode_serial, //< 指定协议驱动的连接模式支持串口
- // cmnenum_linkmode_network,
- cmnenum_linktype_none,
- cmnenum_linkquantity_singleline_singlelink, // 该协议只使用单通道单链接
- u8"HISENSEAIRV301"
- );
- // 设置参数
-
- auto optList = cmnproto_ui_optlist__create_by_str_v2(
- u8"PROTO_VERSION",
- u8"协议版本号",
- u8"协议版本号",
- u8"1");
-
-
- MEGOPP_UTIL__ON_SCOPE_CLEANUP([&optList] { cmnproto_ui_optlist_destruct(&optList); });
- cmnproto_params_lineopt_append(
- _param,
- u8"通信参数",
- optList
- );
- }
- cmnec_t AirProtocol::initialize_cb(cmnproto_handle _handle)
- {
- handle_ = _handle;
- handle_.timerStart(10);
- cmnerrno_t ret = 0;
- ret = handle_.lineGet(line_);
- eqpt_ = handle_.eqptGet();
- if (ret) {
- return CMNERRNO_ERROR;
- }
- ver_ = eqpt_.getOptionString("PROTO_VERSION");
- auto ver = atoi(ver_.c_str());
- // region 设置查询命令
- current_cmd_index_ = 0;
- // 遥测
- queryCmd_.push_back(0x42);
- // 遥信
- queryCmd_.push_back(0x43);
- // 告警
- queryCmd_.push_back(0x44);
- // 告警
- queryCmd_.push_back(0x51);
- // 33版本之后的
- if(ver >= 33 )
- { // 系统参数
- queryCmd_.push_back(0xC2);
- // 系统参数
- queryCmd_.push_back(0x47);
- }
- // endregion 设置查询命令
- return 0;
- }
- cmnec_t AirProtocol::terminate_cb()
- {
- handle_ = nullptr;
- line_ = nullptr;
- eqpt_.reset();
- memset(buffer,0, sizeof(buffer));
- current_cmd_index_ = -1;
- return 0;
- }
- cmnec_t AirProtocol::link_new_cb(cmnlink_ref _link)
- {
- // eqpt_.onlineStateChange(cmnenum_ostate_online);
- currentLink_ = _link;
- return 0;
- }
- cmnec_t AirProtocol::link_del_cb(cmnlink_ref _link)
- {
- if (currentLink_ == _link)
- currentLink_.reset();
- // eqpt_.onlineStateChange(cmnenum_ostate_offline);
- return 0;
- }
- cmnec_t AirProtocol::line_change_cb()
- {
- ver_ = eqpt_.getOptionString("PROTO_VERSION");
- return 0;
- }
- cmnec_t AirProtocol::process_cb()
- {
- // auto readCode = currBlock_.readCode();
- // auto dataAddr = currBlock_.addr();
- current_cmd_index_++;
- current_cmd_index_ = current_cmd_index_ %queryCmd_.size();
- const uint8_t queryCmd = queryCmd_.at(current_cmd_index_);
- cmnproto_log_debug(handle_.native(), "当前命令码: %02X,序号:%d", queryCmd, current_cmd_index_);
- // 获取通道版本号
- if(queryCmd == 0x42)
- {
- this->pack_yc_data();
- }
- else if(queryCmd == 0x43)
- {
- this->pack_yx_data();
- }
- else if(queryCmd == 0x44)
- {
- this->pack_alarm_data();
- }
- else if (queryCmd == 0x51)
- {
- this->pack_product_data();
- }
- else if (queryCmd == 0x47)
- {
- this->pack_query_data();
- }
- else if (queryCmd == 0xC2)
- {
- this->pack_yc1_data();
- }
- return CMNERRNO_OK;
- }
- void AirProtocol::pack_yc_data()
- {
- uint8_t data[1];
- // 打包并发送
- this->pack_data(data, 0, 0x60, 0x42);
- }
- void AirProtocol::unpack_yc_data( uint8_t* buf)
- {
- Cmnpp::Proto::ValueChange vchange;
- // 获取所有的通讯块
- const auto blockList = eqpt_.blockList();
- // 获取第一个通讯块
- const auto block = blockList.at(0);
- for(size_t i = 0; i < block.itemSize(); i++)
- {
- auto item = block.itemAt(i);
- if (!item)
- {
- continue;
- }
- if (item.addr() >= 100)
- {
- continue;
- }
- auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
- if (!p)
- {
- continue;
- }
- const int addr = item.addr();
- ret_value r_value;
- parse_value(item, buf, addr, r_value);
- if (r_value.type == 0) {
- vchange.append(p, r_value.double_value);
- }
- else {
- vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
- }
- //changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
-
- }
- update_changes(vchange);
- }
- void AirProtocol::pack_yc1_data()
- {
- uint8_t data[1];
- // 打包并发送
- this->pack_data(data, 0, 0x60, 0xC2);
- }
- void AirProtocol::unpack_yc1_data(uint8_t* buf)
- {
- Cmnpp::Proto::ValueChange vchange;
- // 获取所有的通讯块
- const auto blockList = eqpt_.blockList();
- // 获取第一个通讯块
- const auto block = blockList.at(0);
- for (size_t i = 0; i < block.itemSize(); i++)
- {
- auto item = block.itemAt(i);
- if (!item)
- {
- continue;
- }
- if (item.addr() < 100 || item.addr() >= 1000)
- {
- continue;
- }
- auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
- if (!p)
- {
- continue;
- }
- const int addr = item.addr() % 100;
- ret_value r_value;
- parse_value(item, buf, addr, r_value);
- if (r_value.type == 0) {
- vchange.append(p, r_value.double_value);
- }
- else {
- vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
- }
- // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
- }
- update_changes(vchange);
- }
- void AirProtocol::pack_query_data()
- {
- uint8_t data[1];
- // 打包并发送
- this->pack_data(data, 0, 0x60, 0x47);
- }
- void AirProtocol::unpack_query_data(uint8_t* buf)
- {
- Cmnpp::Proto::ValueChange vchange;
- // 获取所有的通讯块
- const auto blockList = eqpt_.blockList();
- // 获取第一个通讯块
- const auto block = blockList.at(3);
- for (size_t i = 0; i < block.itemSize(); i++)
- {
- auto item = block.itemAt(i);
- if (!item)
- {
- continue;
- }
- auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
- if (!p)
- {
- continue;
- }
- const int addr = item.addr();
- ret_value r_value;
- parse_value(item, buf, addr, r_value);
- if (r_value.type == 0) {
- vchange.append(p, r_value.double_value);
- }
- else {
- vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
- }
- // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
- }
- update_changes(vchange);
- }
- void AirProtocol::pack_yx_data()
- {
- uint8_t data[1];
- // 打包并发送
- this->pack_data(data, 0, 0x60, 0x43);
- }
- void AirProtocol::unpack_yx_data(uint8_t* buf)
- {
- Cmnpp::Proto::ValueChange vchange;
- // 获取所有的通讯块
- const auto blockList = eqpt_.blockList();
- // 获取第一个通讯块
- const auto block = blockList.at(1);
- for(size_t i = 0; i < block.itemSize(); i++)
- {
- auto item = block.itemAt(i);
- if (!item)
- {
- continue;
- }
- if(item.addr() >= 100)
- {
- continue;
- }
- auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
- if (!p)
- {
- continue;
- }
- const int addr = item.addr();
- ret_value r_value;
- parse_value(item, buf, addr, r_value);
- if (r_value.type == 0) {
- vchange.append(p, r_value.double_value);
- }
- else {
- vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
- }
-
- // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
-
- }
- this->update_changes(vchange);
- }
- void AirProtocol::pack_yk_data(const uint8_t ctrl_code)
- {
- uint8_t data[1];
- data[0] = ctrl_code;
- this->pack_data(data, 1, 0x60, 0x45);
- }
- void AirProtocol::unpack_yk_data(const uint8_t* buf)
- {
- frameMsg_ = handle_.createFrameMsg(eqpt_);
- frameMsg_.append(cmnproto_level_enum_info, 0, 0,
- u8"控制开关响应:%d", buf[7]);
- handle_.pushRecv(currentLink_, eqpt_, frameMsg_, buf_);
- }
- void AirProtocol::pack_alarm_data()
- {
- uint8_t data[1];
- this->pack_data(data, 0, 0x60, 0x44);
- }
- void AirProtocol::unpack_alarm_data(uint8_t* buf)
- {
- Cmnpp::Proto::ValueChange vchange;
- // 获取所有的通讯块
- const auto blockList = eqpt_.blockList();
- // 获取第一个通讯块
- const auto block = blockList.at(1);
- for(size_t i = 0; i < block.itemSize(); i++)
- {
- auto item = block.itemAt(i);
- if (!item)
- {
- continue;
- }
- if(item.addr() < 100 || item.addr() >= 1000)
- {
- continue;
- }
- auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
- if (!p)
- {
- continue;
- }
- const int addr = item.addr()%100;
- ret_value r_value;
- parse_value(item, buf, addr, r_value);
- if (r_value.type == 0) {
- vchange.append(p, r_value.double_value);
- }
- else {
- vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
- }
- // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
-
- }
- update_changes(vchange);
- }
- void AirProtocol::pack_product_data()
- {
- uint8_t data[1];
- this->pack_data(data, 0, 0x60, 0x51);
- }
- void AirProtocol::unpack_product_data(uint8_t* buf)
- {
- Cmnpp::Proto::ValueChange vchange;
- // 获取所有的通讯块
- const auto blockList = eqpt_.blockList();
- // 获取第一个通讯块
- const auto block = blockList.at(3);
- for (size_t i = 0; i < block.itemSize(); i++)
- {
- auto item = block.itemAt(i);
- if (!item)
- {
- continue;
- }
- auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
- if (!p)
- {
- continue;
- }
- const int addr = item.addr();
- ret_value r_value;
- parse_value(item, buf, addr, r_value);
- if (r_value.type == 0) {
- vchange.append(p, r_value.double_value);
- }
- else {
- vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
- }
- // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
- }
- update_changes(vchange);
- }
- cmnec_t AirProtocol::operate_cb(cmnproto_operate_ref_const _oper)
- {
- // 操作请求
- const auto op = Cmnpp::Proto::OperateRef::Ref(_oper);
- switch (op.type())
- {
- case cmnenum_operate_type_remote_ctrl_exec:
- {
- this->pack_yk_data(static_cast<uint8_t>(op.value()));
- }
- default:
- break;
- }
- // 操作响应
- Cmnpp::Proto::OperateReply(op, 0, u8"操作成功");
- return 1;
- }
- cmnec_t AirProtocol::parse_cb()
- {
- cmnerrno_t ret = 0;
- // frameMsg_ = handle_.createFrameMsg(eqpt_);
- // frameMsg_.append(cmnproto_level_enum_info, 0, 0, u8"该报文长度为 %d 字节", static_cast<int>(buf_.size()));
- // MEGOPP_UTIL__ON_SCOPE_CLEANUP([this] { handle_.pushRecv(currentLink_, eqpt_, frameMsg_, buf_); });
-
- uint8_t index = 1;
- // 版本号
- uint8_t ver = DataHelper::read_uint8_ascii(buffer, index);
- // 地址
- uint8_t add = DataHelper::read_uint8_ascii(buffer, index);
- // cid1
- uint8_t cid1 = DataHelper::read_uint8_ascii(buffer, index);
- // cid2
- uint8_t cid2 = DataHelper::read_uint8_ascii(buffer, index);
- // 长度
- uint8_t len_buf[2];
- DataHelper::buffer_from_ascii_uint8(len_buf, buffer +index, 4);
- int lenID = DataHelper::get_len(len_buf);
- auto code = queryCmd_.at(current_cmd_index_);
- index += 4;
- // 读取数据
- // 遥测
- if (code == 0x42 )
- {
- this->unpack_yc_data(buffer + index);
- }
- // 遥信
- else if(code == 0x43)
- {
- this->unpack_yx_data(buffer + index);
- }
- else if(code == 0x44)
- {
- this->unpack_alarm_data(buffer + index);
- }
- else if(code == 0x45)
- {
- this->unpack_yk_data(buffer + index);
- }
- else if (code == 0x51)
- {
- this->unpack_product_data(buffer + index);
- }
- else if (code == 0xC2) {
- this->unpack_yc1_data(buffer + index);
- }
- else if (code == 0x47) {
- this->unpack_query_data(buffer + index);
- }
- else
- {
- frameMsg_.append(cmnproto_level_enum_error, 0, 0,
- u8"未知报文类型:%d", code);
- ret = CMNERRNO_ERROR;
- }
- return 0;
- }
- comm_integer_t AirProtocol::read_cb(cmnlink_ref _link)
- {
-
- auto linkCleanup = megopp::util::scope_cleanup__create([&] {
- currentLink_.readBufferClear();
- });
- memepp::variable_buffer buf_tmp_;
- currentLink_.readAll(buf_tmp_);
- // 追加到buf_
- buf_.append(buf_tmp_);
- buf_tmp_.clear();
- // 寻找EOI
- auto soiIndex = -1;
- auto eoiIndex = -1;
- // cmnproto_log_debug(handle_.native(), "报文长度:%d", buf_.size());
- for (size_t i = 0; i < buf_.size(); ++i)
- {
- if(soiIndex == -1 && buf_.at(i) == 0x7E)
- {
- soiIndex = i;
- }
- if(eoiIndex == -1 && buf_.at(i) == 0x0D)
- {
- eoiIndex = i;
- break;
- }
- }
- if (soiIndex == -1 )
- {
- cmnproto_log_debug(handle_.native(), "寻找SOI失败,继续等待");
- return 0;
- }
- if (eoiIndex == -1)
- {
- cmnproto_log_debug(handle_.native(), "寻找EOI失败,继续等待");
- return 0;
- }
- const auto buff_size = eoiIndex-soiIndex+1;
- memset(buffer, 0, 255);
- memcpy(buffer, buf_.data() + soiIndex, buff_size);
- // 拷贝一份出来,用于输出日志
- const memepp::variable_buffer print_buf_(buffer, buff_size);
- // 移除已拷贝了,将剩余的往前移
- if(soiIndex < buf_.size()-1)
- {
- buf_.remove(0, eoiIndex + 1);
- }
- if(eoiIndex - soiIndex < 18)
- {
- cmnproto_log_debug(handle_.native(), "报文长度过短,正常报文应不小于18");
- auto msg = handle_.createFrameMsg(eqpt_, cmnproto_level_enum_warn, 0, 0, u8"报文长度过短,正常报文应不小于18");
- // 开发者需要自己把接收到的报文信息通过handle_发到报文查看功能
- handle_.pushRecv(currentLink_, eqpt_, msg, print_buf_);
- return -1;
- }
- // 校验码
- uint8_t checksum[2];
- // 计算出来的校验码
- DataHelper::check_sum(buffer , 1, static_cast<int>(buff_size) - 6, checksum);
- // 当前校验码
- uint8_t rptCheckSum[2];
- DataHelper::buffer_from_ascii_uint8(rptCheckSum, buffer + (buff_size-5), 4);
- if (checksum[0] != rptCheckSum[0] || checksum[1] != rptCheckSum[1])
- {
- cmnproto_log_debug(handle_.native(), u8"校验码不正确,报文校验码:%02X%02X, 计算校验码:%02X%02X", rptCheckSum[0], rptCheckSum[1], checksum[0], checksum[1]);
- auto msg = handle_.createFrameMsg(eqpt_, cmnproto_level_enum_warn, 0, 0, u8"校验码不正确,报文校验码:%02X%02X, 计算校验码:%02X%02X", rptCheckSum[0], rptCheckSum[1], checksum[0], checksum[1]);
- handle_.pushRecv(currentLink_, eqpt_, msg, print_buf_);
- return 0;
- }
- auto msg = handle_.createFrameMsg(eqpt_, cmnproto_level_enum_info, 0, 0, u8"正确报文");
- // 开发者需要自己把接收到的报文信息通过handle_发到报文查看功能
- handle_.pushRecv(currentLink_, eqpt_, msg, print_buf_);
- // 拷贝到正确的报文缓存中
- linkCleanup.cancel();
- // 返回报文长度则回调parse_cb(),返回0则不回调parse_cb()
- return buff_size;
-
-
- }
- int AirProtocol::pack_data(uint8_t data[], const int data_len, const uint8_t cid1, const uint8_t cid2)
- {
- uint8_t index = 0;
- uint8_t buf[255];
- // SOI
- buf[index++] = 0x7E;
- auto ver = atoi(line_.getOptionString("PROTO_VERSION").c_str());
- // VER
- buf[index++] = 0x30 + (ver/10);
- buf[index++] = 0x30 + (ver%10);
- //DataHelper::buffer_copy_uint8_ascii(buf, 0x00, index) ;
- // 地址
- DataHelper::buffer_copy_uint8_ascii(buf, static_cast<uint8_t>(eqpt_.addr()), index) ;
- // CID1
- DataHelper::buffer_copy_uint8_ascii(buf, cid1, index);
- // CID2
- DataHelper::buffer_copy_uint8_ascii(buf, cid2, index);
- // 数据长度
- uint8_t len[2];
- DataHelper::generate_len(data_len, len);
- DataHelper::buffer_copy_uint8_ascii(buf, len[0], index);
- DataHelper::buffer_copy_uint8_ascii(buf, len[1], index);
- // 写入数据区
- memcpy(buf + index, data, data_len);
- index += data_len;
- // 校验码
- uint8_t checksum[2];
- DataHelper::check_sum(buf, 1, static_cast<int>(index) - 1, checksum);
- DataHelper::buffer_copy_uint8_ascii(buf, checksum[0], index);
- DataHelper::buffer_copy_uint8_ascii(buf, checksum[1], index);
- buf[index++] = 0x0D;
- cmnproto_log_debug(handle_.native(), "准备发送命令: CID1:%02X,CID2:%02X,", cid1, cid2);
- return handle_.send(currentLink_, buf, index);
- }
- void AirProtocol::parse_value(Cmnpp::Template::BlockItem item, uint8_t* buf, int addr, ret_value &r_value)
- {
- const auto type = cmntmpblk_item_datatype(item.native());
- if (type == cmnenum_value_int8 || type == cmnenum_value_int16 || type == cmnenum_value_int32)
- {
- uint8_t data[4];
- DataHelper::buffer_from_ascii_uint8(data, buf + addr, item.dataLength());
- auto value = DataHelper::get_signed_int(data, static_cast<int>(item.dataLength() / 2));
- r_value.double_value = value * item.coefficient();
- if (queryCmd_[current_cmd_index_] == 0x47) {
- cmnproto_log_debug(handle_.native(), "命令类型: %02X, 内存地址: %d, 数据长度:%d, 值:%f", queryCmd_[current_cmd_index_], item.addr(), item.dataLength(), r_value.double_value);
- }
- }
- else if (type== cmnenum_value_uint8 || type == cmnenum_value_uint16 || type == cmnenum_value_uint32)
- {
- uint8_t data[4];
- DataHelper::buffer_from_ascii_uint8(data, buf + addr, item.dataLength());
- auto value = DataHelper::get_unsigned_int(data, static_cast<int>(item.dataLength()/2));
- r_value.double_value = value * item.coefficient();
- if (queryCmd_[current_cmd_index_] == 0x47) {
- cmnproto_log_debug(handle_.native(), "命令类型: %02X, 内存地址: %d, 数据长度:%d, 值:%f", queryCmd_[current_cmd_index_], item.addr(), item.dataLength(), r_value.double_value);
- }
- }
- else if (type == cmnenum_value_string)
- {
- uint8_t data[100];
- memcpy(r_value.str_value,buf + addr, item.dataLength());
- r_value.str_len = static_cast<int>(item.dataLength());
- r_value.type = 1;
- if (queryCmd_[current_cmd_index_] == 0x47) {
- cmnproto_log_debug(handle_.native(), "命令类型: %02X, 内存地址: %d, 数据长度:%d, 值:%s", queryCmd_[current_cmd_index_], item.addr(), item.dataLength(), r_value.str_value);
- }
- }
-
- }
- void AirProtocol::update_changes(Cmnpp::Proto::ValueChange vchange)
- {
- // 更新至存储
- if (vchange.size() > 0) {
- int ret = vchange.updates();
- cmnproto_log_debug(handle_.native(), "命令类型: %02X, 总共数据量:%d, 更新值数量:%d", queryCmd_[current_cmd_index_], vchange.size(), ret);
- }
- }
- // 该函数是插件的退出函数,该函数会被插件加载器调用
- CMN_PLUGIN_API int64_t cmnplugin_exit()
- {
- return CMNERRNO_OK;
- }
- // 该函数是插件的入口函数,该函数会被插件加载器调用
- CMN_PLUGIN_API int64_t cmnplugin_initialize(
- const cmnplugin_init_params* _params, rsize_t _structSize, cmnplugin_exit_func_t* _func)
- {
- Cmnpp::IProtocolRegistrar registrar(_params, _structSize);
- auto ret = registrar.initialize();
- if (ret < 0)
- return CMNERRNO_ERROR;
- ret = registrar.registerObject<AirProtocol>("HISENSEAIRV301");
- if (ret < 0)
- return CMNERRNO_ERROR;
-
- *_func = cmnplugin_exit;
- return 0;
- }
|