工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 移动开发 > 正文
用C#开发.NET CF 蓝牙通信模块
[文章信息]
作者: lornshrimp
时间:2005-03-31
出处:blog
责任编辑:方舟
[文章导读]
在Windows Mobile软件开发中.Net正扮演着日益重要的角色
advertisement
专题教程宝典
【软件应用】
【办公软件】
【图形图像】
【网页制作】
【操作系统】
【网络安全】
【程序开发】
【日报周刊】
【多媒体教程】
· 天极软件应用多媒体教程
· 电脑美术设计中的色彩表现
· MFC程序员的WTL开发指南
· 多媒体系列教程:网页设计制作
· Win XP系统应用技巧完全手册
· 3Ds max7多边形建模从入门到进阶
· 微软对.NET失去信心?.NET专家激起千层浪
· Outlook Express使用技巧大全(一)
· 抢先试用卡巴斯基 KIS 2006
· 自己动手制作手机Flash主题动画
[正文]

1 2  下一页

  在Windows Mobile软件开发中.Net正扮演着日益重要的角色,我们已经可以看到很多用.Net CF开发的软件,这些软件涉及到了日常应用的方方面面。在智能设备的软件开发中,无线互联是一个相当重要的一块,我们可以看到,红外几乎是所有智能设备的标配,而蓝牙也日益在越来越多的智能设备上出现,有了硬件,显然要有相应的软件相关的应用。

  我们也知道,用.NET CF开发红外通信应用时相当轻松的,因为.NET CF中有一个命名空间System.Net.IrDA就是用于红外通信的通信模块。但是,.NET CF中还没有关于蓝牙通信的模块,所以目前来讲做这方面的开发还有一定的困难。下面,就谈谈如何用C#开发.NET CF蓝牙通信模块。

  一. 基本要点

  首先明确一点,因为涉及到驱动硬件的问题,所以仅靠了解C#开发的相关知识显然是无法完成开发的,我们必须对C++开发有所了解。但是为了简单起见,我们不希望用C++写半行代码,所有的编码工作全部使用C#,也就是说,使用的开发环境只需要使用Visual Studio.net,不需要用其他的编辑器。

  作为开发这类驱动硬件的程序的知识准备,您需要了解C++的基本知识,知道头文件是怎么一回事,知道托管代码如何与非托管代码交互。因为本文的核心是说明如何开发.net CF蓝牙通信模块,所以前述这些准备知识并不作讲述。

  二. 关于蓝牙

  做蓝牙通信模块开发,自然先要知道蓝牙通信是怎么一回事。在我看来,蓝牙通信应该和红外通信模块类似,当然我是从开发者的角度来讲,抽象化以后应该就是这样,当然蓝牙和红外通信也有很多不一样的地方,这在面向对象设计里面怎么讲,我想一定有很多人理解的比我透彻。好了,这就是我们的基本思路了。我曾经在网上查过关于蓝牙开发的文章,很多人在.net CF开发中把蓝牙通信当作一个串行通信来处理,这也是不错的,但是我不是很喜欢,因为这样做的话,并不是针对蓝牙来开发的,换言之,在使用过程中,需要先手动开启蓝牙,配对,连接,建立串行通道,然后开启应用程序使用,你还要在应用程序中设置串行端口,对最终用户来讲,这是非常麻烦的。我觉得,这样的解决方案冠上蓝牙通信的名头简直就是……不多说了,书归正传。

  在红外通信中,我们知道,设备的DeviceID是一个Byte数组,那么蓝牙设备的DeviceID什么样子呢?我想这个大家都很清楚,是一串以“:”分隔的16进制数字。

  红外通信中,一般而言红外并没有开启、关闭之类的状态,但是蓝牙有开启、关闭、可发现三种状态。

  红外没有安全设置,而蓝牙有安全设置,所以我们需要对蓝牙设备进行配对,而红外通信这部需要。

  我们查看.net的Socket地址族里有IrDA,但是没有蓝牙相关的地址族,这是我们需要解决的问题。

  三. 获取设备ID

  1.获取本地设备的ID

  我们查看Window CE 4.2的SDK文档,得知获取本地设备ID的函数是BthReadLocalAddr,在btdrt.dll中。SDK文档中的英文原文是这样的:“This function retrieves the Bluetooth address of the current device.”好了,知道了这个就好说了:

  首先封装本地托管函数:

[DllImport("Btdrt.dll", SetLastError=true)]

public static extern int BthReadLocalAddr(byte[] pba);

  这个函数得到的本地DeviceID也是一组byte数组,为了向人们显示出来,我们要把它变为String:

string text1 = "";

text1 = text1 + pba[5].ToString("X2") + ":";

text1 = text1 + pba [4].ToString("X2") + ":";

text1 = text1 + pba [3].ToString("X2") + ":";

text1 = text1 + pba [2].ToString("X2") + ":";

text1 = text1 + pba [1].ToString("X2") + ":";

return (text1 + pba [0].ToString("X2"));

  2.获取远程设备的ID

  其实谈到获取远程设备的ID就涉及到如何去发现远程设备了,所以这里就一并把发现设备的方法也说明了吧。 发现设备需要用到三个Winsock API,分别是WSALookupServiceBegin、WSALookupServiceNext和WSALookupServiceEnd,这三个API到底起什么作用可以去查看Windows CE 4.2的SDK,这里就不详细解释了,只谈一下几个需要注意的地方。

  WSALookupServiceBegin的函数原形是这样的:

INT WSALookupServiceBegin(

LPWSAQUERYSET lpqsRestrictions,

DWORD dwControlFlags,

LPHANDLE lphLookup

);

  我们用托管代码进行包装:

[DllImport("ws2.dll", EntryPoint="WSALookupServiceBegin", SetLastError=true)]

public static extern int CeLookupServiceBegin(byte[] pQuerySet, LookupFlags dwFlags, ref int lphLookup);

  可以看到,本来lpqsRestrictions是一个struct,经过包装后在托管代码中成为了byte[],我们计算好该struct大概要占用多少个byte,struct中每一个成员在byte数组中的位置是怎样的,装配出来就好了。

  由于是针对蓝牙作的开发,所以我们要查看一下这些参数应该是哪些值。Windows CE 4.2的SDK中说,蓝牙开发时,struct LPWSAQUERYSET中的如下成员应当为这些值:

The dwSize member must be sizeof(WSAQUERYSET).

The lpBlob member (itself a pointer to a BLOB structure) is optional, but if used, the device inquire parameters valid for LUP_FLUSHCACHE are the following:

The cbSize member of the BLOB structure must be sizeof(BTH_QUERY_DEVICE).

The pBlobData member is a pointer to a BTH_QUERY_DEVICE structure, for which the LAP member is the Bluetooth inquiry access code, and the length member is the length of the inquiry, in seconds.

The dwNameSpace member must be NS_BTH.

All other WSAQUERYSET members are ignored.

  具体什么意思各位可以自己去理解,我想比我翻译出来要好些,毕竟我英语很差的。根据以上要求,我们这样装配pQuerySet:

byte[] buffer1 = new byte[0x400];

BitConverter.GetBytes(60).CopyTo(buffer1, 0);

GCHandle handle1 = GCHandle.Alloc(blob1.ToByteArray(), GCHandleType.Pinned);

IntPtr ptr1 = handle1.AddrOfPinnedObject();

BitConverter.GetBytes((int) (ptr1.ToInt32() + 4)).CopyTo(buffer1, 0x38);

  另外的两个API也照类似方法调用即可。

  在调用了WSALookupServiceNext之后,bytes数组pQuerySet中便包含了远程设备的地址信息,下面我们需要把它找出来。通过阅读SDK中WSAQUERYSET结构的说明和计算每个成员的位置之后,我们写出如下代码:

int num5 = BitConverter.ToInt32(buffer1, 0x30);

int num6 = Marshal.ReadInt32((IntPtr) num5, 8);

int num7 = Marshal.ReadInt32((IntPtr) num5, 12);

SocketAddress address1 = new SocketAddress(AddressFamily.Unspecified, num7);

  因为.net框架的地址族里面没有蓝牙,所以我们这里用的是AddressFamily.Unspecified。

  然后的工作就是从中获取远程设备的ID了:

  前面我们已经计算出,这个Address里面的前六个字节是byte数组形式的设备ID,第七到第二十二个字节是蓝牙的Service Guid,在后面四个字节是端口号,所以我们只需要分别提取出来即可。


1 2  下一页

天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • 基于CMPP2及东软API短信平台的开发
  • 2004开发技术年度综述之移动开发
  • Windows Mobile开发环境搭建指南
  • ucLinux下sqlite数据库移植全攻略
  • C++ SDK+Symbian开发入门之部署
  • 3家搜索引擎集体诉讼8848 吕春维未敢出席
  • 杨元庆:没有准备不会获批的备用方案
  • 【315】华硕笔记本电脑漏电 存在设计缺陷
  • 军队信息化诞生新领域 电子军务呼之欲出
  • 世界经济论坛公布信息化程度全球最新排名
  • 2004政务绩效评估:政府门户尚处于发展阶段
  • 甲骨文出资5.15亿美元 意图收购RetekInc
  • 技术并购:帮你突破传统增长的“天花板”
  • Advertisement

    天极无线
    经典名曲 华语流行 欧美风情 人声音效 原声大碟
    你好周杰伦-安又琪
    直线-张韶涵
    天边-张韶涵
    看我72变-蔡依林
    乱世佳人-Twins
    全世界下雨-张娜拉
    我们的爱-飞儿乐队
    分手快乐-梁静茹
    爱在西元前-周杰伦
    三万英尺-迪克牛仔
    爱如潮水-张信哲
    爱情宣言-齐秦
    寻找玛依拉-刀郎
    驼铃-刀郎
    老鼠爱大米-杨臣刚
    功夫主题曲
    仙剑主题曲杀破狼
    天下无贼片尾曲
    冲动的惩罚-刀郎
    情人-刀郎
    爱情-莫文蔚
    挪威的森林-伍佰
    奔跑 - 羽泉
    因为爱 - 羽泉
      ·时尚女人圈
    ·经典影视专集
    ·美女秀场
    ·美丽大自然专题
    ·流行金曲
    ·科幻电影特区
    | 最新推荐
    ·你好周杰伦
    ·杀破狼
    ·寻找玛依拉
    ·孤单公园
    ·男人海洋
    | 魔术铃声
    ·少女丰胸
    ·少妇丰胸
    ·减肥魔铃
    ·增高魔铃
    ·美容魔铃

    今日报价查询 更多报价